Browse files

[CommandLine] Some cleanup and docs

  • Loading branch information...
1 parent cccf82d commit 38bb2e5f150b05042a2c900f2b3dc04d0a72cce6 @Whiteknight committed Aug 28, 2012
View
66 src/commandline/ArgumentDef.winxed
@@ -1,13 +1,28 @@
+/* Argument Definitions.
+ Represents the forward declarations of the different arguments. These
+ definitions are used during argument processing to parse out expected
+ arguments.
+*/
class Rosella.CommandLine.ArgumentDef
{
- var raw_defs;
- var prepared_defs;
+ // TODO: We might consider breaking this up into different strategy subclasses
+ // depending on raw_defs format, and adding a factory to choose between
+ // them
+ var raw_defs; // The raw argument definitions from the user
+ var prepared_defs; // The prepared/processed argument definitions
+
+ // Constructor
function ArgumentDef(var raw_defs)
{
self.raw_defs = raw_defs;
}
+ /* Public Methods
+ */
+
+ // Get a description or help message. This message will show all argument
+ // definitions and the description message associated with each
function get_description(var sb = new 'StringBuilder')
{
// TODO: Prepend a usage string with program name
@@ -21,6 +36,29 @@ class Rosella.CommandLine.ArgumentDef
return sb;
}
+ // Process the input definitions format into a format suitable to use for
+ // argument processing.
+ function get_definitions()
+ {
+ if (self.prepared_defs != null)
+ return self.prepared_defs;
+
+ var arg_defs = Rosella.get_string_string_hash();
+ var raw_defs = self.raw_defs;
+ if (does(raw_defs, "hash"))
+ self.__prepare_arg_defs_hash(raw_defs, arg_defs);
+ else if (does(raw_defs, "array"))
+ self.__prepare_arg_defs_array(raw_defs, arg_defs);
+ else
+ Rosella.Error.error("Unknown argument definition type '%s'", typeof(raw_defs));
+ self.prepared_defs = arg_defs;
+ return arg_defs;
+ }
+
+ /* Private Helper Methods
+ */
+
+ // Get a description message for a new-style def hash
function __get_description_hash(var raw_defs, var sb)
{
int max = 0;
@@ -51,34 +89,19 @@ class Rosella.CommandLine.ArgumentDef
return sb;
}
+ // Get a description message for an old-style array of arrays
function __get_description_array(var raw_defs, var sb)
{
// TODO
}
- function get_definitions()
- {
- if (self.prepared_defs != null)
- return self.prepared_defs;
-
- var arg_defs = Rosella.get_string_string_hash();
- var raw_defs = self.raw_defs;
- if (does(raw_defs, "hash"))
- self.__prepare_arg_defs_hash(raw_defs, arg_defs);
- else if (does(raw_defs, "array"))
- self.__prepare_arg_defs_array(raw_defs, arg_defs);
- else
- Rosella.Error.error("Unknown argument definition type '%s'", typeof(raw_defs));
- self.prepared_defs = arg_defs;
- return arg_defs;
- }
-
/* We can handle defs of the following types:
foo f
foo=s f=s
foo=[] f=[]
foo={} f={}
*/
+ // Get a processed definition hash for a new-style hash
function __prepare_arg_defs_hash(var defs, var arg_defs)
{
for (string arg_def in defs) {
@@ -111,10 +134,9 @@ class Rosella.CommandLine.ArgumentDef
}
}
- // TODO: If we get an array of arrays, try to copy old-style
- // GetOpt::Obj format
+ // Get a processed definition hash for an old-style array of arrays
function __prepare_arg_defs_array(var defs, var arg_defs)
{
-
+ // TODO
}
}
View
5 src/commandline/Arguments.winxed
@@ -133,8 +133,7 @@ class Rosella.CommandLine.Arguments
return self.remainder;
}
- // Get the raw list of args. Notice that this list is destroyed during
- // parsing
+ // Get the raw list of args.
function raw_args()
{
return self.raw_args;
@@ -150,7 +149,6 @@ class Rosella.CommandLine.Arguments
return false;
}
- // Once parsed, provide keyed access to the cache
function get_string_keyed[vtable](string name)
{
if (exists self.named_cache[name])
@@ -160,7 +158,6 @@ class Rosella.CommandLine.Arguments
return "";
}
- // Once parsed, provide keyed access to the cache
function get_pmc_keyed[vtable](string name)
{
if (exists self.named_cache[name])
View
11 src/commandline/ModeCondition.winxed
@@ -1,15 +1,24 @@
+/* A condition for a ProgramMode
+ Each ProgramMode besides the default mode may have one or more conditions
+ that must be met before that ProgramMode can be activated. This is the
+ abstract parent class of specialized conditions.
+*/
class Rosella.CommandLine.ModeCondition
{
+ // Determine if this condition is satisifed by the given list of parsed
+ // arguments
function is_satisfied(var args)
{
return false;
}
+ // Get a description of this condition, for use in a help/usage message
function get_description(var sb)
{
}
}
+// Condition that requires the presence of a given flag
class Rosella.CommandLine.ModeCondition.FlagSet : Rosella.CommandLine.ModeCondition
{
var flagname;
@@ -34,6 +43,7 @@ class Rosella.CommandLine.ModeCondition.FlagSet : Rosella.CommandLine.ModeCondit
}
}
+// Condition that requires a given scalar-valued flag
class Rosella.CommandLine.ModeCondition.ScalarValue : Rosella.CommandLine.ModeCondition
{
var name;
@@ -66,6 +76,7 @@ class Rosella.CommandLine.ModeCondition.ScalarValue : Rosella.CommandLine.ModeCo
}
}
+// Condition that uses a user-specified predicate function
class Rosella.CommandLine.ModeCondition.GenericFunc : Rosella.CommandLine.ModeCondition
{
var func;
View
55 src/commandline/Program.winxed
@@ -28,7 +28,10 @@ class Rosella.CommandLine.Program
};
}
- function arguments(var raw_defs)
+ /* Public Methods
+ */
+
+ function define_arguments(var raw_defs)
{
self.arg_defs = new Rosella.CommandLine.ArgumentDef(raw_defs);
return self;
@@ -87,29 +90,6 @@ class Rosella.CommandLine.Program
exit(exit_code);
}
- function __find_mode(var args)
- {
- for (string modename in self.modes) {
- var mode = self.modes[modename];
- if (mode.can_accept(args))
- return mode;
- }
- return self.default_mode;
- }
-
- // On error, try to execute the error handler, if any.
- function try_handle_error(var e)
- {
- var on_error = self.on_error;
- if (on_error == null) {
- if (e == null)
- Rosella.Error.error("Unknown error during dispatch");
- else
- throw e;
- }
- on_error(e);
- }
-
function get_help_text()
{
var sb = new 'StringBuilder';
@@ -129,4 +109,31 @@ class Rosella.CommandLine.Program
push(sb, "\n");
return self.arg_defs.get_description(sb);
}
+
+ /* Private Methods
+ */
+
+ function __find_mode(var args)
+ {
+ for (string modename in self.modes) {
+ var mode = self.modes[modename];
+ if (mode.can_accept(args))
+ return mode;
+ }
+ return self.default_mode;
+ }
+
+ // On error, try to execute the error handler, if any.
+ function try_handle_error(var e)
+ {
+ var on_error = self.on_error;
+ if (on_error == null) {
+ if (e == null) {
+ // If we fail to dispatch, just dump the usage message
+ say(self.get_help_text());
+ } else
+ throw e;
+ }
+ on_error(e);
+ }
}
View
9 src/commandline/ProgramMode.winxed
@@ -31,12 +31,16 @@ class Rosella.CommandLine.ProgramMode
return self;
}
+ // Set a custom usage message
function set_usage(string usage)
{
self.usage = usage;
return self;
}
+ // Get the complete usage message, as a combination of the Program usage
+ // message, usage messages for the different modes, and usage messages
+ // for all argument definitions.
function get_usage(string program_name, var sb)
{
var usage = self.usage;
@@ -76,6 +80,7 @@ class Rosella.CommandLine.ProgramMode
return self.func;
}
+ // Require the existence of a flag
function require_flag(string name)
{
if (self.conditions == null)
@@ -85,6 +90,7 @@ class Rosella.CommandLine.ProgramMode
return self;
}
+ // Require a specific scalar value
function require_value(string name, string value)
{
if (self.conditions == null)
@@ -94,6 +100,7 @@ class Rosella.CommandLine.ProgramMode
return self;
}
+ // Require a predicate function to return true
function require_condition(var f)
{
if (self.conditions == null)
@@ -104,6 +111,8 @@ class Rosella.CommandLine.ProgramMode
}
}
+// Default program mode, similar to a normal mode but with no preconditions
+// and a more generic usage message
class Rosella.CommandLine.ProgramMode.Default : Rosella.CommandLine.ProgramMode
{
function Default() { self.name = ""; }

0 comments on commit 38bb2e5

Please sign in to comment.