home *** CD-ROM | disk | FTP | other *** search
/ H4CK3R 5 / hacker05 / 05_HACK_05.ISO / programacao / freewrap / TCLLIBsampleApp.exe / sample / tcllib / tcllib1.0 / cmdline / cmdline.tcl next >
Encoding:
Text File  |  2001-08-17  |  7.6 KB  |  268 lines

  1. # cmdline.tcl --
  2. #
  3. #    This package provides a utility for parsing command line
  4. #    arguments that are processed by our various applications.
  5. #    It also includes a utility routine to determine the app
  6. #    name for use in command line errors.
  7. #
  8. # Copyright (c) 1998-2000 by Ajuba Solutions.
  9. # See the file "license.terms" for information on usage and redistribution
  10. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11. # RCS: @(#) $Id: cmdline.tcl,v 1.9 2001/08/02 16:38:06 andreas_kupries Exp $
  12.  
  13. package require Tcl 8.2
  14. package provide cmdline 1.1
  15. namespace eval cmdline {
  16.     namespace export getArgv0 getopt getfiles getoptions usage
  17. }
  18.  
  19. # Load the typed versions of these functions
  20. source [file join [file dirname [info script]] typedCmdline.tcl]
  21.  
  22. # cmdline::getopt --
  23. #
  24. #    The cmdline::getopt works in a fashion like the standard
  25. #    C based getopt function.  Given an option string and a 
  26. #    pointer to an array or args this command will process the
  27. #    first argument and return info on how to procede.
  28. #
  29. # Arguments:
  30. #    argvVar        Name of the argv list that you
  31. #            want to process.  If options are found the
  32. #            arg list is modified and the processed arguments
  33. #            are removed from the start of the list.
  34. #    optstring    A list of command options that the application
  35. #            will accept.  If the option ends in ".arg" the
  36. #            getopt routine will use the next argument as 
  37. #            an argument to the option.  Otherwise the option    
  38. #            is a boolean that is set to 1 if present.
  39. #    optVar        The variable pointed to by optVar
  40. #            contains the option that was found (without the
  41. #            leading '-' and without the .arg extension).
  42. #    valVar        Upon success, the variable pointed to by valVar
  43. #            contains the value for the specified option.
  44. #            This value comes from the command line for .arg
  45. #            options, otherwise the value is 1.
  46. #            If getopt fails, the valVar is filled with an
  47. #            error message.
  48. #
  49. # Results:
  50. #     The getopt function returns 1 if an option was found, 0 if no more
  51. #     options were found, and -1 if an error occurred.
  52.  
  53. proc cmdline::getopt {argvVar optstring optVar valVar} {
  54.     upvar 1 $argvVar argsList
  55.  
  56.     upvar 1 $optVar option
  57.     upvar 1 $valVar value
  58.  
  59.     # default settings for a normal return
  60.     set value ""
  61.     set option ""
  62.     set result 0
  63.  
  64.     # check if we're past the end of the args list
  65.     if {[llength $argsList] != 0} {
  66.  
  67.     # if we got -- or an option that doesn't begin with -, return (skipping
  68.     # the --).  otherwise process the option arg.
  69.     switch -glob -- [set arg [lindex $argsList 0]] {
  70.         "--" {
  71.         set argsList [lrange $argsList 1 end]
  72.         }
  73.  
  74.         "-*" {
  75.         set option [string range $arg 1 end]
  76.  
  77.         if {[lsearch -exact $optstring $option] != -1} {
  78.             # Booleans are set to 1 when present
  79.             set value 1
  80.             set result 1
  81.             set argsList [lrange $argsList 1 end]
  82.         } elseif {[lsearch -exact $optstring "$option.arg"] != -1} {
  83.             set result 1
  84.             set argsList [lrange $argsList 1 end]
  85.             if {[llength $argsList] != 0} {
  86.             set value [lindex $argsList 0]
  87.             set argsList [lrange $argsList 1 end]
  88.             } else {
  89.             set value "Option \"$option\" requires an argument"
  90.             set result -1
  91.             }
  92.         } else {
  93.             set value "Illegal option \"$option\""
  94.             set result -1
  95.         }
  96.         }
  97.         default {
  98.         # Skip ahead
  99.         }
  100.     }
  101.     }
  102.  
  103.     return $result
  104. }
  105.  
  106. # cmdline::getoptions --
  107. #
  108. #    Process a set of command line options, filling in defaults
  109. #    for those not specified.  This also generates an error message
  110. #    that lists the allowed flags if an incorrect flag is specified.
  111. #
  112. # Arguments:
  113. #    arglistVar    The name of the argument list, typically argv
  114. #    optlist        A list-of-lists where each element specifies an option
  115. #            in the form:
  116. #                flag default comment
  117. #            If flag ends in ".arg" then the value is taken from the
  118. #            command line. Otherwise it is a boolean and appears in
  119. #            the result if present on the command line. If flag ends
  120. #            in ".secret", it will not be displayed in the usage.
  121. #    usage        Text to include in the usage display. Defaults to
  122. #            "options:"
  123. #
  124. # Results
  125. #    Name value pairs suitable for using with array set.
  126.  
  127. proc cmdline::getoptions {arglistVar optlist {usage options:}} {
  128.     upvar 1 $arglistVar argv
  129.     set opts {? help}
  130.     foreach opt $optlist {
  131.     set name [lindex $opt 0]
  132.     if {[regsub -- .secret$ $name {} name] == 1} {
  133.         # Need to hide this from the usage display and getopt
  134.     }   
  135.     lappend opts $name
  136.     if {[regsub -- .arg$ $name {} name] == 1} {
  137.  
  138.         # Set defaults for those that take values.
  139.  
  140.         set default [lindex $opt 1]
  141.         set result($name) $default
  142.     } else {
  143.         # The default for booleans is false
  144.         set result($name) 0
  145.     }
  146.     }
  147.     set argc [llength $argv]
  148.     while {[set err [cmdline::getopt argv $opts opt arg]]} {
  149.     if {$err < 0} {
  150.         error [cmdline::usage $optlist $usage]
  151.     }
  152.     set result($opt) $arg
  153.     }
  154.     if {[info exist result(?)] || [info exists result(help)]} {
  155.     error [cmdline::usage $optlist $usage]
  156.     }
  157.     return [array get result]
  158. }
  159.  
  160. # cmdline::usage --
  161. #
  162. #    Generate an error message that lists the allowed flags.
  163. #
  164. # Arguments:
  165. #    optlist        As for cmdline::getoptions
  166. #    usage        Text to include in the usage display. Defaults to
  167. #            "options:"
  168. #
  169. # Results
  170. #    A formatted usage message
  171.  
  172. proc cmdline::usage {optlist {usage {options:}}} {
  173.     set str "[cmdline::getArgv0] $usage\n"
  174.     foreach opt [concat $optlist \
  175.         {{help "Print this message"} {? "Print this message"}}] {
  176.     set name [lindex $opt 0]
  177.     if {[regsub -- .secret$ $name {} name] == 1} {
  178.         # Hidden option
  179.         continue
  180.     }
  181.     if {[regsub -- .arg$ $name {} name] == 1} {
  182.         set default [lindex $opt 1]
  183.         set comment [lindex $opt 2]
  184.         append str [format " %-20s %s <%s>\n" "-$name value" \
  185.             $comment $default]
  186.     } else {
  187.         set comment [lindex $opt 1]
  188.         append str [format " %-20s %s\n" "-$name" $comment]
  189.     }
  190.     }
  191.     return $str
  192. }
  193.  
  194. # cmdline::getfiles --
  195. #
  196. #    Given a list of file arguments from the command line, compute
  197. #    the set of valid files.  On windows, file globbing is performed
  198. #    on each argument.  On Unix, only file existence is tested.  If
  199. #    a file argument produces no valid files, a warning is optionally
  200. #    generated.
  201. #
  202. #    This code also uses the full path for each file.  If not
  203. #    given it prepends [pwd] to the filename.  This ensures that
  204. #    these files will never comflict with files in our zip file.
  205. #
  206. # Arguments:
  207. #    patterns    The file patterns specified by the user.
  208. #    quiet        If this flag is set, no warnings will be generated.
  209. #
  210. # Results:
  211. #    Returns the list of files that match the input patterns.
  212.  
  213. proc cmdline::getfiles {patterns quiet} {
  214.     set result {}
  215.     if {$::tcl_platform(platform) == "windows"} {
  216.     foreach pattern $patterns {
  217.         regsub -all -- {\\} $pattern {\\\\} pat
  218.         set files [glob -nocomplain -- $pat]
  219.         if {$files == {}} {
  220.         if {! $quiet} {
  221.             puts stdout "warning: no files match \"$pattern\""
  222.         }
  223.         } else {
  224.         foreach file $files {
  225.             lappend result $file
  226.         }
  227.         }
  228.     }
  229.     } else {
  230.     set result $patterns
  231.     }
  232.     set files {}
  233.     foreach file $result {
  234.     # Make file an absolute path so that we will never conflict
  235.     # with files that might be contained in our zip file.
  236.     set fullPath [file join [pwd] $file]
  237.     
  238.     if {[file isfile $fullPath]} {
  239.         lappend files $fullPath
  240.     } elseif {! $quiet} {
  241.         puts stdout "warning: no files match \"$file\""
  242.     }
  243.     }
  244.     return $files
  245. }
  246.  
  247. # cmdline::getArgv0 --
  248. #
  249. #    This command returns the "sanitized" version of argv0.  It will strip
  250. #    off the leading path and remove the ".bin" extensions that our apps
  251. #    use because they must be wrapped by a shell script.
  252. #
  253. # Arguments:
  254. #    None.
  255. #
  256. # Results:
  257. #    The application name that can be used in error messages.
  258.  
  259. proc cmdline::getArgv0 {} {
  260.     global argv0
  261.  
  262.     set name [file tail $argv0]
  263.     return [file rootname $name]
  264. }
  265.  
  266.  
  267.