Guest User

Untitled

a guest
Jun 21st, 2018
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.93 KB | None | 0 0
  1. #!perl
  2. ###
  3. ### (c) Copyright 1992,1993,1994,1995 Scott D. Lawrence
  4. ### All rights reserved.
  5. ###
  6. ### Permission is hereby granted to use, copy, and distribute this code
  7. ### in any way provided that the above copyright is included in all copies.
  8. ### No warranty is of suitability for any purpose is provided by the author.
  9. ###
  10. ### [That having been said, if you find a problem in this package (or use
  11. ### it and don't find a problem) I would love to hear from you:
  12. ### scott (at) skrb (dot) org
  13. ###
  14. ### This package provides the routine 'getargs' for parsing command line
  15. ### arguments. It automates most of a standard command line interface by
  16. ### taking a picture of the expected arguments of the form:
  17. ###
  18. ### ( <4tuple> [, <4tuple> ]... )
  19. ###
  20. ### <4tuple> ::= <type>, <keyword>, <size>, <variable>
  21. ###
  22. ### <type> ::= '-' for switch arguments (these are order independent
  23. ### among themselves, but must all appear before any
  24. ### positional arguments)
  25. ### 'm' for mandatory positional arguments
  26. ### 'o' for optional positional arguments
  27. ### 'h' provides the help text; keyword and size are ignored.
  28. ### The contents of the scalar named in the variable
  29. ### are saved to print in the usage message. This may
  30. ### appear anywhere in the argument picture, but only
  31. ### one may be specified.
  32. ###
  33. ### <keyword> ::= string to match for switch arguments
  34. ### (also used to print for usage of postional arguments)
  35. ###
  36. ### To provide a short form and long form for an argument,
  37. ### use '<short>|<long>'; the long form will be recognized
  38. ### only if preceded by a double dash. For example:
  39. ### '-', 'f|force' specifies the switches '-f' and '--force'
  40. ### as being equivalent.
  41. ###
  42. ### <size> ::= number of values to consume from ARGV
  43. ### 0 ::= increment variable using '++'
  44. ### (used for flag switches)
  45. ### >1 ::= set list variable to next 'n' values
  46. ### -1 ::= set list variable to remaining values
  47. ### (for switch arguments, the values following
  48. ### '--' are not consumed)
  49. ###
  50. ### <variable> ::= name of variable (not including $ or @) to assign
  51. ### argument value into
  52. ###
  53. ### Provides -usage, --usage, -help, --help, and -?
  54. ### (if the 'usage' or 'help' switches are specified in the picture,
  55. ### the caller will get it like any other switch).
  56. ###
  57. ### Provides '--' for the end of switch arguments.
  58. ###
  59. ### Switch and Optional arguments not specified in @ARGV are not
  60. ### defined by getargs - you can either test for that or just assign
  61. ### them default values before calling getargs.
  62. ###
  63. ### @ARGV is not modified.
  64. ### The getargs routine can be used for interactive command parsing
  65. ### by reading the command, splitting the results into @ARGV, and
  66. ### calling getargs as you would for the real command line.
  67. ###
  68. ### Returns 1 if @ARGV parsed correctly according to the picture; if not,
  69. ### it prints the usage message and returns 0;
  70. ###
  71. ### Example:
  72. ###
  73. ### $HelpText = <<_HELP_TEXT_;
  74. ### This is the help text for this command.
  75. ### _HELP_TEXT_
  76. ###
  77. ### &getargs( '-', 'flag', 0, 'Flag'
  78. ### ,'-', 'value', 1, 'Value'
  79. ### ,'-', 'list', 2, 'List'
  80. ### ,'-', 'a|alternate', 1, 'Alternate'
  81. ### ,'-', 'values', -1, 'Values'
  82. ### ,'m', 'mandatory', 1, 'Mandatory'
  83. ### ,'m', 'mandatory2', 1, 'Mandatory2'
  84. ### ,'o', 'optional', 1, 'Optional'
  85. ### ,'h', '', 0, 'HelpText'
  86. ### ) || exit;
  87. ###
  88. ### Produces the usage picture:
  89. ###
  90. ################################################################
  91. ###
  92. ### testargs
  93. ### [-flag]
  94. ### [-value <value>]
  95. ### [-list <list> <list>]
  96. ### [-a|--alternate <alternate>]
  97. ### [-values <values> ... ]
  98. ### [--]
  99. ### <mandatory>
  100. ### <mandatory2>
  101. ### [<optional>]
  102. ###
  103. ### This is the help text for this command.
  104. ################################################################
  105. ###
  106. ### and sets the variables: $Mandatory, $Mandatory2
  107. ### and (if specified): $Flag, $Value, @List, $Alternate,
  108. ### @Values, $Optional
  109. ###
  110.  
  111. package getargs;
  112.  
  113. sub main'getargs #'
  114. {
  115. local(@Picture) = @_;
  116.  
  117. # Now parse the argument picture
  118. local( $Type, $Keyword, $Key, $Size, $Variable, $Tuple );
  119. local( %Sizes, %Switches );
  120. local( $Options, $Mandatories, @Positional, $Target, %Targets );
  121.  
  122. for ( $Tuple = 0; $Tuple < $#Picture; $Tuple += 4 )
  123. {
  124. ( $Type, $Keyword, $Size, $Variable ) = @Picture[ $Tuple..$Tuple+3 ];
  125.  
  126. if ( $Keyword =~ /^([a-zA-Z])\|([a-zA-Z]+[-a-zA-Z]*)$/ )
  127. {
  128. die "Only switch keywords may have alternate values ('|')"
  129. if ( $Type ne '-' );
  130.  
  131. local( $ShortKey, $LongKey ) = ( $1, "-$2" );
  132.  
  133. $Sizes{ $ShortKey } = $Size;
  134. $Targets{ $ShortKey } = $Variable;
  135.  
  136. $Sizes{ $LongKey } = $Size;
  137. $Targets{ $LongKey } = $Variable;
  138. }
  139. elsif ( $Type ne 'h' )
  140. {
  141. $Sizes{ $Keyword } = $Size;
  142. $Targets{ $Keyword } = $Variable;
  143. }
  144.  
  145. if ( $Type eq '-' ) # switch argument
  146. {
  147. die "Switch Argument specified after Positionals\n"
  148. if ( $Options || $Mandatories )
  149. }
  150. elsif ( $Type eq 'm' ) # mandatory positional argument
  151. {
  152. die "Optional Arg in picture before Mandatory Arg\n"
  153. if $Options;
  154. $Mandatories++;
  155. push( @Positional, $Keyword );
  156. }
  157. elsif ( $Type eq 'o' ) # optional positional argument
  158. {
  159. $Options++;
  160. push( @Positional, $Keyword );
  161. }
  162. elsif ( $Type eq 'h' ) # help message argument
  163. {
  164. defined( $HelpText )
  165. && die "Only one help text parameter ('h') allowed.\n";
  166.  
  167. $Assignment = '$HelpText = $main\''.$Variable.';';
  168. eval $Assignment;
  169. $HelpText || die "Help text specified in $Variable is empty\n";
  170. }
  171. else
  172. {
  173. die "Undefined Type: $Type\n";
  174. }
  175. }
  176.  
  177. ###
  178. ### Parse Switch Arguments from Actual Argument List
  179. ###
  180.  
  181. local( @ActualArgs ) = @ARGV;
  182.  
  183. Switch:
  184. while ( $#Switches && ($_ = shift @ActualArgs) )
  185. {
  186. if ( /^--$/ ) ## force end of options processing
  187. {
  188. #print "END OPTIONS\n"; #<DEBUG
  189. last Switch;
  190. }
  191. elsif ( /^-\?$/ )
  192. {
  193. &usage( @Picture );
  194. return 0;
  195. }
  196. elsif ( /^-\d+/ ) ## numeric argument - not an option
  197. {
  198. unshift( @ActualArgs, $_ );
  199. last Switch;
  200. }
  201. elsif ( s/^-// ) ## looks like a switch...
  202. {
  203. if ( $Target = $Targets{ $_ } )
  204. {
  205. &assign_value( $Target, $Sizes{ $_ } );
  206. }
  207. elsif ( /^-?(usage|help)$/ )
  208. {
  209. &usage( @Picture );
  210. return 0;
  211. }
  212. else
  213. {
  214. warn "Unknown switch -$_\n";
  215. &usage( @Picture );
  216. return 0;
  217. }
  218. }
  219. else
  220. {
  221. #print "END SWITCHES?\n"; #<DEBUG
  222. unshift( @ActualArgs, $_ );
  223. last Switch;
  224. }
  225. } # Switch
  226.  
  227. ###
  228. ### Parse Positional Arguments from Actual Argument List
  229. ###
  230.  
  231. Positional:
  232. while( $_ = shift( @Positional ) )
  233. {
  234. &assign_value( $Targets{ $_ }, $Sizes{ $_ } ) || last Positional;
  235. $Mandatories--;
  236. }
  237.  
  238. if ( @ActualArgs )
  239. {
  240. warn "Too many arguments: @ActualArgs\n";
  241. &usage( @Picture );
  242. 0;
  243. }
  244. elsif ( $Mandatories > 0 )
  245. {
  246. warn "Not enough arguments supplied\n";
  247. &usage( @Picture );
  248. 0;
  249. }
  250. else
  251. {
  252. 1;
  253. }
  254.  
  255. } # sub getargs
  256.  
  257. sub assign_value
  258. {
  259. local ( $Target, $Size ) = @_;
  260. local ( $Assignment );
  261.  
  262. if ( $Size <= @ActualArgs )
  263. {
  264. Assign:
  265. {
  266. $Assignment = '$main\''.$Target.'++;'
  267. , last Assign if ( $Size == 0 );
  268. $Assignment = '$main\''.$Target.' = shift @ActualArgs;'
  269. , last Assign if ( $Size == 1 );
  270. $Assignment =
  271. '@main\''.$Target.' = @ActualArgs[ $[..$[+$Size-1 ],@ActualArgs = @ActualArgs[ $[+$Size..$#ActualArgs ];'
  272. , last Assign if ( $Size > 1 );
  273. $Assignment =
  274. 'push( @main\''.$Target.', shift @ActualArgs )
  275. while ($#ActualArgs >= $[) && ($ActualArgs[$[] ne \'--\');'
  276.  
  277. , last Assign if ( $Size == -1 );
  278. die "Invalid argument type in picture\n";
  279. }
  280.  
  281. eval $Assignment;
  282. 1;
  283. }
  284. else
  285. {
  286. @ActualArgs = ();
  287. 0;
  288. }
  289. }
  290.  
  291. sub usage
  292. {
  293. local( $CommandName ) = $0;
  294. $CommandName =~ s\^.*/\\;
  295. print "Usage:\n";
  296. print " $CommandName";
  297. local( @Picture ) = @_;
  298. local( $Type, $Keyword, $Size, $Tuple, $Switches );
  299.  
  300. $Switches = 0;
  301. Switch: for ( $Tuple = 0; $Tuple < $#Picture; $Tuple += 4 )
  302. {
  303. ( $Type, $Keyword, $Size ) = @Picture[ $Tuple..$Tuple+2 ];
  304.  
  305. if ( $Type eq "-" ) # switch argument
  306. {
  307. $Switches++;
  308.  
  309. print "\n "." " x length($CommandName)." ";
  310.  
  311. if ( $Keyword =~ s/(.+)\|(.+)/$2/ )
  312. {
  313. print " [-$1|--$2";
  314. }
  315. else
  316. {
  317. print " [-$Keyword";
  318. }
  319. if ( $Size == -1 )
  320. {
  321. print " <$Keyword> ... ";
  322. }
  323. print " <$Keyword>" while ( $Size-- > 0 );
  324. print "]";
  325. }
  326. }
  327.  
  328. print "\n "." " x length($CommandName)." [--]" if $Switches;
  329.  
  330. Positional: for ( $Tuple = 0; $Tuple < $#Picture; $Tuple += 4 )
  331. {
  332. ( $Type, $Keyword, $Size ) = @Picture[ $Tuple..$Tuple+2 ];
  333.  
  334. print "\n "." " x length($CommandName)." " unless $Type eq '-';
  335.  
  336. if ( $Type eq "m" ) # mandatory positional argument
  337. {
  338. if ( $Size == -1 )
  339. {
  340. print " <$Keyword> ...";
  341. last Positional;
  342. }
  343. print " <$Keyword>" while ( $Size-- > 0 );
  344. }
  345. elsif ( $Type eq "o" ) # optional positional argument
  346. {
  347. if ( $Size == -1 )
  348. {
  349. print " [<$Keyword>] ...";
  350. last Positional;
  351. }
  352. print " [<$Keyword>" while ( $Size-- > 0 );
  353. print "]";
  354. }
  355. }
  356.  
  357. print "\n";
  358.  
  359. defined( $HelpText ) && print $HelpText;
  360. }
  361. 1;
  362.  
  363. ### Local Variables: ***
  364. ### mode:perl ***
  365. ### End: ***
Add Comment
Please, Sign In to add comment