Skip to content
This repository
Browse code

[CommandLine] Some cleanup and docs

  • Loading branch information...
commit 38bb2e5f150b05042a2c900f2b3dc04d0a72cce6 1 parent cccf82d
Andrew Whitworth authored
66 src/commandline/ArgumentDef.winxed
... ... @@ -1,13 +1,28 @@
  1 +/* Argument Definitions.
  2 + Represents the forward declarations of the different arguments. These
  3 + definitions are used during argument processing to parse out expected
  4 + arguments.
  5 +*/
1 6 class Rosella.CommandLine.ArgumentDef
2 7 {
3   - var raw_defs;
4   - var prepared_defs;
  8 + // TODO: We might consider breaking this up into different strategy subclasses
  9 + // depending on raw_defs format, and adding a factory to choose between
  10 + // them
5 11
  12 + var raw_defs; // The raw argument definitions from the user
  13 + var prepared_defs; // The prepared/processed argument definitions
  14 +
  15 + // Constructor
6 16 function ArgumentDef(var raw_defs)
7 17 {
8 18 self.raw_defs = raw_defs;
9 19 }
10 20
  21 + /* Public Methods
  22 + */
  23 +
  24 + // Get a description or help message. This message will show all argument
  25 + // definitions and the description message associated with each
11 26 function get_description(var sb = new 'StringBuilder')
12 27 {
13 28 // TODO: Prepend a usage string with program name
@@ -21,6 +36,29 @@ class Rosella.CommandLine.ArgumentDef
21 36 return sb;
22 37 }
23 38
  39 + // Process the input definitions format into a format suitable to use for
  40 + // argument processing.
  41 + function get_definitions()
  42 + {
  43 + if (self.prepared_defs != null)
  44 + return self.prepared_defs;
  45 +
  46 + var arg_defs = Rosella.get_string_string_hash();
  47 + var raw_defs = self.raw_defs;
  48 + if (does(raw_defs, "hash"))
  49 + self.__prepare_arg_defs_hash(raw_defs, arg_defs);
  50 + else if (does(raw_defs, "array"))
  51 + self.__prepare_arg_defs_array(raw_defs, arg_defs);
  52 + else
  53 + Rosella.Error.error("Unknown argument definition type '%s'", typeof(raw_defs));
  54 + self.prepared_defs = arg_defs;
  55 + return arg_defs;
  56 + }
  57 +
  58 + /* Private Helper Methods
  59 + */
  60 +
  61 + // Get a description message for a new-style def hash
24 62 function __get_description_hash(var raw_defs, var sb)
25 63 {
26 64 int max = 0;
@@ -51,34 +89,19 @@ class Rosella.CommandLine.ArgumentDef
51 89 return sb;
52 90 }
53 91
  92 + // Get a description message for an old-style array of arrays
54 93 function __get_description_array(var raw_defs, var sb)
55 94 {
56 95 // TODO
57 96 }
58 97
59   - function get_definitions()
60   - {
61   - if (self.prepared_defs != null)
62   - return self.prepared_defs;
63   -
64   - var arg_defs = Rosella.get_string_string_hash();
65   - var raw_defs = self.raw_defs;
66   - if (does(raw_defs, "hash"))
67   - self.__prepare_arg_defs_hash(raw_defs, arg_defs);
68   - else if (does(raw_defs, "array"))
69   - self.__prepare_arg_defs_array(raw_defs, arg_defs);
70   - else
71   - Rosella.Error.error("Unknown argument definition type '%s'", typeof(raw_defs));
72   - self.prepared_defs = arg_defs;
73   - return arg_defs;
74   - }
75   -
76 98 /* We can handle defs of the following types:
77 99 foo f
78 100 foo=s f=s
79 101 foo=[] f=[]
80 102 foo={} f={}
81 103 */
  104 + // Get a processed definition hash for a new-style hash
82 105 function __prepare_arg_defs_hash(var defs, var arg_defs)
83 106 {
84 107 for (string arg_def in defs) {
@@ -111,10 +134,9 @@ class Rosella.CommandLine.ArgumentDef
111 134 }
112 135 }
113 136
114   - // TODO: If we get an array of arrays, try to copy old-style
115   - // GetOpt::Obj format
  137 + // Get a processed definition hash for an old-style array of arrays
116 138 function __prepare_arg_defs_array(var defs, var arg_defs)
117 139 {
118   -
  140 + // TODO
119 141 }
120 142 }
5 src/commandline/Arguments.winxed
@@ -133,8 +133,7 @@ class Rosella.CommandLine.Arguments
133 133 return self.remainder;
134 134 }
135 135
136   - // Get the raw list of args. Notice that this list is destroyed during
137   - // parsing
  136 + // Get the raw list of args.
138 137 function raw_args()
139 138 {
140 139 return self.raw_args;
@@ -150,7 +149,6 @@ class Rosella.CommandLine.Arguments
150 149 return false;
151 150 }
152 151
153   - // Once parsed, provide keyed access to the cache
154 152 function get_string_keyed[vtable](string name)
155 153 {
156 154 if (exists self.named_cache[name])
@@ -160,7 +158,6 @@ class Rosella.CommandLine.Arguments
160 158 return "";
161 159 }
162 160
163   - // Once parsed, provide keyed access to the cache
164 161 function get_pmc_keyed[vtable](string name)
165 162 {
166 163 if (exists self.named_cache[name])
11 src/commandline/ModeCondition.winxed
... ... @@ -1,15 +1,24 @@
  1 +/* A condition for a ProgramMode
  2 + Each ProgramMode besides the default mode may have one or more conditions
  3 + that must be met before that ProgramMode can be activated. This is the
  4 + abstract parent class of specialized conditions.
  5 +*/
1 6 class Rosella.CommandLine.ModeCondition
2 7 {
  8 + // Determine if this condition is satisifed by the given list of parsed
  9 + // arguments
3 10 function is_satisfied(var args)
4 11 {
5 12 return false;
6 13 }
7 14
  15 + // Get a description of this condition, for use in a help/usage message
8 16 function get_description(var sb)
9 17 {
10 18 }
11 19 }
12 20
  21 +// Condition that requires the presence of a given flag
13 22 class Rosella.CommandLine.ModeCondition.FlagSet : Rosella.CommandLine.ModeCondition
14 23 {
15 24 var flagname;
@@ -34,6 +43,7 @@ class Rosella.CommandLine.ModeCondition.FlagSet : Rosella.CommandLine.ModeCondit
34 43 }
35 44 }
36 45
  46 +// Condition that requires a given scalar-valued flag
37 47 class Rosella.CommandLine.ModeCondition.ScalarValue : Rosella.CommandLine.ModeCondition
38 48 {
39 49 var name;
@@ -66,6 +76,7 @@ class Rosella.CommandLine.ModeCondition.ScalarValue : Rosella.CommandLine.ModeCo
66 76 }
67 77 }
68 78
  79 +// Condition that uses a user-specified predicate function
69 80 class Rosella.CommandLine.ModeCondition.GenericFunc : Rosella.CommandLine.ModeCondition
70 81 {
71 82 var func;
55 src/commandline/Program.winxed
@@ -28,7 +28,10 @@ class Rosella.CommandLine.Program
28 28 };
29 29 }
30 30
31   - function arguments(var raw_defs)
  31 + /* Public Methods
  32 + */
  33 +
  34 + function define_arguments(var raw_defs)
32 35 {
33 36 self.arg_defs = new Rosella.CommandLine.ArgumentDef(raw_defs);
34 37 return self;
@@ -87,29 +90,6 @@ class Rosella.CommandLine.Program
87 90 exit(exit_code);
88 91 }
89 92
90   - function __find_mode(var args)
91   - {
92   - for (string modename in self.modes) {
93   - var mode = self.modes[modename];
94   - if (mode.can_accept(args))
95   - return mode;
96   - }
97   - return self.default_mode;
98   - }
99   -
100   - // On error, try to execute the error handler, if any.
101   - function try_handle_error(var e)
102   - {
103   - var on_error = self.on_error;
104   - if (on_error == null) {
105   - if (e == null)
106   - Rosella.Error.error("Unknown error during dispatch");
107   - else
108   - throw e;
109   - }
110   - on_error(e);
111   - }
112   -
113 93 function get_help_text()
114 94 {
115 95 var sb = new 'StringBuilder';
@@ -129,4 +109,31 @@ class Rosella.CommandLine.Program
129 109 push(sb, "\n");
130 110 return self.arg_defs.get_description(sb);
131 111 }
  112 +
  113 + /* Private Methods
  114 + */
  115 +
  116 + function __find_mode(var args)
  117 + {
  118 + for (string modename in self.modes) {
  119 + var mode = self.modes[modename];
  120 + if (mode.can_accept(args))
  121 + return mode;
  122 + }
  123 + return self.default_mode;
  124 + }
  125 +
  126 + // On error, try to execute the error handler, if any.
  127 + function try_handle_error(var e)
  128 + {
  129 + var on_error = self.on_error;
  130 + if (on_error == null) {
  131 + if (e == null) {
  132 + // If we fail to dispatch, just dump the usage message
  133 + say(self.get_help_text());
  134 + } else
  135 + throw e;
  136 + }
  137 + on_error(e);
  138 + }
132 139 }
9 src/commandline/ProgramMode.winxed
@@ -31,12 +31,16 @@ class Rosella.CommandLine.ProgramMode
31 31 return self;
32 32 }
33 33
  34 + // Set a custom usage message
34 35 function set_usage(string usage)
35 36 {
36 37 self.usage = usage;
37 38 return self;
38 39 }
39 40
  41 + // Get the complete usage message, as a combination of the Program usage
  42 + // message, usage messages for the different modes, and usage messages
  43 + // for all argument definitions.
40 44 function get_usage(string program_name, var sb)
41 45 {
42 46 var usage = self.usage;
@@ -76,6 +80,7 @@ class Rosella.CommandLine.ProgramMode
76 80 return self.func;
77 81 }
78 82
  83 + // Require the existence of a flag
79 84 function require_flag(string name)
80 85 {
81 86 if (self.conditions == null)
@@ -85,6 +90,7 @@ class Rosella.CommandLine.ProgramMode
85 90 return self;
86 91 }
87 92
  93 + // Require a specific scalar value
88 94 function require_value(string name, string value)
89 95 {
90 96 if (self.conditions == null)
@@ -94,6 +100,7 @@ class Rosella.CommandLine.ProgramMode
94 100 return self;
95 101 }
96 102
  103 + // Require a predicate function to return true
97 104 function require_condition(var f)
98 105 {
99 106 if (self.conditions == null)
@@ -104,6 +111,8 @@ class Rosella.CommandLine.ProgramMode
104 111 }
105 112 }
106 113
  114 +// Default program mode, similar to a normal mode but with no preconditions
  115 +// and a more generic usage message
107 116 class Rosella.CommandLine.ProgramMode.Default : Rosella.CommandLine.ProgramMode
108 117 {
109 118 function Default() { self.name = ""; }

0 comments on commit 38bb2e5

Please sign in to comment.
Something went wrong with that request. Please try again.