@@ -24,7 +24,7 @@ namespace dream
2424 typedef std::vector<String> CommandParams;
2525
2626 // Command function
27- typedef std::function<void (CommandParams)> CommandFunction;
27+ typedef std::function<void (CommandParams params, Print& output )> CommandFunction;
2828
2929 class CommandLineInterface
3030 {
@@ -44,6 +44,9 @@ namespace dream
4444 // Source for continuous reading
4545 Stream *_source = nullptr ;
4646
47+ // Output for command result
48+ Print *_output = nullptr ;
49+
4750 // Function to call in case of error
4851 std::function<void (String)> _errorHandler;
4952
@@ -95,21 +98,61 @@ namespace dream
9598 return result;
9699 }
97100
101+ // Run command
102+ void runCommand (String command, Print *output)
103+ {
104+ if (command.isEmpty ())
105+ {
106+ _errorHandler (" Command is empty" );
107+ return ;
108+ }
109+
110+ if (output == nullptr )
111+ {
112+ _errorHandler (" Output not specified" );
113+ return ;
114+ }
115+
116+ // Trim string
117+ command.trim ();
118+
119+ // Parse command name and arguments
120+ const String name = getFirstArgument (command, ' ' );
121+ const std::vector<String> params = splitString (command.substring (name.length ()), ' ' );
122+
123+ // Find command
124+ for (const Command &c : _commands)
125+ {
126+ if (c.name == name)
127+ {
128+ // Run command
129+ c.run (params, *output);
130+
131+ return ;
132+ }
133+ }
134+
135+ // Command wasn't found
136+ _errorHandler (" Command " + command + " not found" );
137+ return ;
138+ }
139+
98140 public: // --------------------------------------------------------------
99141
100- // Init CLI in basic mode
101- // In this mode you have to manually cal `run(string)` method.
102- CommandLineInterface () { }
142+ // Init CLI with default input and output
143+ CommandLineInterface () : _source(&Serial), _output(&Serial) { }
103144
104- // Init CLI with reading from source
105- // In this mode you have to place `tick()` method call to your `loop()`
106- // or you still can use `run(string)` method as well.
107- CommandLineInterface (Stream *s) : _source(s) { }
108- CommandLineInterface (Stream &s) : _source(&s) { }
145+ // Init CLI with input and output specified
146+ CommandLineInterface (Stream *source, Print *output) : _source(source), _output(output) { }
147+ CommandLineInterface (Stream &source, Print &output) : _source(&source), _output(&output) { }
109148
110- // Change mode to reading from source
149+ // Change source
111150 void setSource (Stream *s) { _source = s; }
112151 void setSource (Stream &s) { _source = &s; }
152+
153+ // Change source
154+ void setOutput (Print *s) { _output = s; }
155+ void setOutput (Print &s) { _output = &s; }
113156
114157 // Set function to call in case of error
115158 // Error message will be set as String argument
@@ -144,30 +187,19 @@ namespace dream
144187 // Run command from string
145188 void run (String command)
146189 {
147- if (command.isEmpty ()) return ;
148-
149- // Trim string
150- command.trim ();
151-
152- // Parse command name and arguments
153- const String name = getFirstArgument (command, ' ' );
154- const std::vector<String> params = splitString (command.substring (name.length ()), ' ' );
190+ runCommand (command, _output);
191+ }
155192
156- // Find command
157- for (const Command &c : _commands)
158- {
159- if (c.name == name)
160- {
161- // Run command
162- c.run (params);
193+ // Run command from string with separate output
194+ void run (String command, Print &output)
195+ {
196+ runCommand (command, &output);
197+ }
163198
164- return ;
165- }
166- }
167-
168- // Command wasn't found
169- _errorHandler (" [CLI] Command " + command + " not found" );
170- return ;
199+ // Run command from string with separate output
200+ void run (String command, Print *output)
201+ {
202+ runCommand (command, output);
171203 }
172204 };
173205}
0 commit comments