├── .gitignore ├── LICENSE ├── README.md ├── examples └── CLITest │ └── CLITest.ino ├── library.json ├── library.properties ├── src ├── CLI.cpp └── CLI.h └── uecide.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | 15 | # Compiler output 16 | *.hex 17 | *.lss 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Majenko Technologies 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | * Neither the name of Majenko Technologies nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | CLI 2 | === 3 | 4 | Command Line stream interface for Arduino etc 5 | -------------------------------------------------------------------------------- /examples/CLITest/CLITest.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | CLI_COMMAND(addFunc); 4 | CLI_COMMAND(helpFunc); 5 | CLI_COMMAND(connectFunc); 6 | 7 | void setup() { 8 | Serial.begin(9600); 9 | CLI.setDefaultPrompt("> "); 10 | CLI.onConnect(connectFunc); 11 | 12 | CLI.addCommand("add", addFunc); 13 | CLI.addCommand("help", helpFunc); 14 | 15 | CLI.addClient(Serial); 16 | } 17 | 18 | void loop() { 19 | CLI.process(); 20 | } 21 | 22 | CLI_COMMAND(addFunc) { 23 | if (argc != 3) { 24 | dev->println("Usage: add "); 25 | return 10; 26 | } 27 | int n1 = atoi(argv[1]); 28 | int n2 = atoi(argv[2]); 29 | dev->print(n1); 30 | dev->print(" + "); 31 | dev->print(n2); 32 | dev->print(" = "); 33 | dev->println(n1 + n2); 34 | return 0; 35 | } 36 | 37 | CLI_COMMAND(helpFunc) { 38 | dev->println("add - Add two numbers together"); 39 | return 0; 40 | } 41 | 42 | CLI_COMMAND(connectFunc) { 43 | dev->println("Welcome to the CLI test."); 44 | dev->println("Type 'help' to list commands."); 45 | dev->println(); 46 | dev->printPrompt(); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CLI", 3 | "keywords": "commandline, serial, terminal", 4 | "description": "Command Line Interface (CLI) system for Arduino", 5 | "repository": 6 | { 7 | "type": "git", 8 | "url": "https://github.com/MajenkoLibraries/CLI" 9 | }, 10 | "version": "1.2.3", 11 | "frameworks": "arduino", 12 | "platforms": "*" 13 | } 14 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=CLI 2 | version=1.2.6 3 | author=Matt Jenkins 4 | maintainer=Matt Jenkins 5 | sentence=Command-line Interface library for Arduino 6 | paragraph=CLI\n===\n\nCommand Line stream interface for Arduino etc\n 7 | url=https://github.com/MajenkoLibraries/CLI 8 | category=Communication 9 | architectures=* 10 | includes=CLI.h 11 | -------------------------------------------------------------------------------- /src/CLI.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, Majenko Technologies 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * * Neither the name of Majenko Technologies nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #include 32 | 33 | CLIServer CLI; 34 | 35 | CLIServer::CLIServer() { 36 | clients = NULL; 37 | commands = NULL; 38 | prompt = NULL; 39 | _caseSensitive = true; 40 | } 41 | 42 | void CLIServer::setCaseInsensitive() { 43 | _caseSensitive = false; 44 | } 45 | 46 | void CLIServer::setCaseSensitive() { 47 | _caseSensitive = true; 48 | } 49 | 50 | boolean CLIServer::isCaseSensitive() { 51 | return _caseSensitive; 52 | } 53 | 54 | 55 | CLIClient *CLIServer::addClient(Stream &dev, void *data) { 56 | return addClient(&dev, data); 57 | } 58 | 59 | CLIClient *CLIServer::addClient(Stream &dev) { 60 | return addClient(&dev, NULL); 61 | } 62 | 63 | CLIClient *CLIServer::addClient(Stream *dev) { 64 | return addClient(dev, NULL); 65 | } 66 | 67 | CLIClient *CLIServer::addClient(Stream *dev, void *data) { 68 | CLIClientList *scan; 69 | CLIClientList *newClient; 70 | 71 | newClient = (CLIClientList *)malloc(sizeof(CLIClientList)); 72 | 73 | newClient->client = new CLIClient(dev); 74 | newClient->client->setPrompt(prompt); 75 | newClient->client->setSessionData(data); 76 | newClient->next = NULL; 77 | if (clients == NULL) { 78 | clients = newClient; 79 | return newClient->client; 80 | } 81 | for (scan = clients; scan->next; scan = scan->next); 82 | scan->next = newClient; 83 | return newClient->client; 84 | } 85 | 86 | void CLIServer::addCommand(const char *command, int (*function)(CLIClient *, int, char **)) { 87 | CLICommand *scan; 88 | CLICommand *newCommand; 89 | 90 | newCommand = (CLICommand *)malloc(sizeof(CLICommand)); 91 | newCommand->command = strdup(command); 92 | newCommand->flags = 0; 93 | newCommand->function = function; 94 | newCommand->next = NULL; 95 | 96 | if (commands == NULL) { 97 | commands = newCommand; 98 | return; 99 | } 100 | for (scan = commands; scan->next; scan = scan->next); 101 | scan->next = newCommand; 102 | } 103 | 104 | void CLIServer::addPrefix(const char *command, int (*function)(CLIClient *, int, char **)) { 105 | CLICommand *scan; 106 | CLICommand *newCommand; 107 | 108 | newCommand = (CLICommand *)malloc(sizeof(CLICommand)); 109 | newCommand->command = strdup(command); 110 | newCommand->flags = CLI_IS_PREFIX; 111 | newCommand->function = function; 112 | newCommand->next = NULL; 113 | 114 | if (commands == NULL) { 115 | commands = newCommand; 116 | return; 117 | } 118 | for (scan = commands; scan->next; scan = scan->next); 119 | scan->next = newCommand; 120 | } 121 | 122 | static inline char *getWord(char *buf) { 123 | static char *ptr = NULL; 124 | char *start, *scan; 125 | char term = ' '; 126 | 127 | if (buf != NULL) { 128 | ptr = buf; 129 | } 130 | 131 | while ((*ptr == ' ' || *ptr == '\t') && *ptr != '\0') { 132 | ptr++; 133 | } 134 | if (*ptr == '\0') { 135 | return NULL; 136 | } 137 | 138 | if (*ptr == '"' || *ptr == '\'') { 139 | term = *ptr; 140 | ptr++; 141 | } 142 | start = ptr; 143 | 144 | while (*ptr != '\0') { 145 | if (*ptr == '\\') { 146 | for (scan = ptr; *scan != '\0'; scan++) { 147 | *scan = *(scan+1); 148 | } 149 | ptr++; 150 | continue; 151 | } 152 | if (*ptr == term || (term == ' ' && *ptr == '\t')) { 153 | *ptr = '\0'; 154 | ptr++; 155 | return start; 156 | } 157 | ptr++; 158 | } 159 | if (ptr == start) { 160 | return NULL; 161 | } 162 | return start; 163 | } 164 | 165 | int CLIClient::readline() { 166 | int rpos; 167 | 168 | if (!dev->available()) { 169 | return -1; 170 | } 171 | 172 | int readch = dev->read(); 173 | 174 | while (readch > 0) { 175 | switch (readch) { 176 | case '\r': // Ignore CR 177 | case '\n': // Return on NL 178 | rpos = pos; 179 | pos = 0; // Reset position index ready for next time 180 | if (willEcho) dev->println(); 181 | if (_redirect != NULL) { 182 | _redirect(this, input, rpos); 183 | return -1; 184 | } 185 | return rpos; 186 | case 8: 187 | case 127: 188 | if (pos > 0) { 189 | pos--; 190 | input[pos] = 0; 191 | if (willEcho) dev->print("\b \b"); 192 | } 193 | break; 194 | default: 195 | if (pos < CLI_BUFFER-2) { 196 | if (willEcho) dev->write(readch); 197 | input[pos++] = readch; 198 | input[pos] = 0; 199 | } 200 | } 201 | readch = dev->read(); 202 | } 203 | // No end of line has been found, so return -1. 204 | return -1; 205 | } 206 | 207 | int CLIClient::parseCommand() { 208 | CLICommand *scan; 209 | char *argv[20]; 210 | int argc; 211 | char *w; 212 | 213 | argc = 0; 214 | w = getWord(input); 215 | while ((argc < 20) && (w != NULL)) { 216 | argv[argc++] = w; 217 | w = getWord(NULL); 218 | } 219 | if (CLI.isCaseSensitive()) { 220 | for (scan = CLI.commands; scan; scan = scan->next) { 221 | if ((scan->flags & CLI_IS_PREFIX) == 0) { 222 | if (strcmp(scan->command, argv[0]) == 0) { 223 | return scan->function(this, argc, argv); 224 | } 225 | } 226 | } 227 | for (scan = CLI.commands; scan; scan = scan->next) { 228 | if ((scan->flags & CLI_IS_PREFIX) != 0) { 229 | if (strncmp(scan->command, argv[0], strlen(scan->command)) == 0) { 230 | return scan->function(this, argc, argv); 231 | } 232 | } 233 | } 234 | } else { 235 | for (scan = CLI.commands; scan; scan = scan->next) { 236 | if ((scan->flags & CLI_IS_PREFIX) == 0) { 237 | if (strcasecmp(scan->command, argv[0]) == 0) { 238 | return scan->function(this, argc, argv); 239 | } 240 | } 241 | } 242 | for (scan = CLI.commands; scan; scan = scan->next) { 243 | if ((scan->flags & CLI_IS_PREFIX) != 0) { 244 | if (strncasecmp(scan->command, argv[0], strlen(scan->command)) == 0) { 245 | return scan->function(this, argc, argv); 246 | } 247 | } 248 | } 249 | } 250 | return -1; 251 | } 252 | 253 | void CLIClient::setSessionData(void *data) { 254 | _sessionData = data; 255 | } 256 | 257 | void *CLIClient::getSessionData() { 258 | return _sessionData; 259 | } 260 | 261 | void CLIServer::process() { 262 | CLIClientList *scan; 263 | for (scan = clients; scan; scan = scan->next) { 264 | uint8_t ctest = scan->client->testConnected(); 265 | 266 | if (ctest == CLIClient::CONNECTED) { 267 | if (_onConnect != NULL) { 268 | _onConnect(scan->client, 0, NULL); 269 | scan->client->printPrompt(); 270 | } 271 | } else if (ctest == CLIClient::DISCONNECTED) { 272 | if (_onDisconnect != NULL) { 273 | _onDisconnect(scan->client, 0, NULL); 274 | } 275 | } 276 | 277 | int rl = scan->client->readline(); 278 | if (rl > 0) { 279 | int rv = scan->client->parseCommand(); 280 | if (rv == -1) { 281 | scan->client->println("Unknown command"); 282 | } else { 283 | if (rv > 0) { 284 | scan->client->print("Error "); 285 | scan->client->println(rv); 286 | } 287 | } 288 | scan->client->printPrompt(); 289 | } else if (rl == 0) { 290 | scan->client->printPrompt(); 291 | } 292 | } 293 | } 294 | 295 | #if (ARDUINO >= 100) 296 | size_t CLIServer::write(uint8_t c) { 297 | #else 298 | void CLIServer::write(uint8_t c) { 299 | #endif 300 | CLIClientList *scan; 301 | for (scan = clients; scan; scan = scan->next) { 302 | scan->client->write(c); 303 | } 304 | #if (ARDUINO > 100) 305 | return 1; 306 | #endif 307 | } 308 | 309 | CLIClient::CLIClient(Stream *d) { 310 | dev = d; 311 | pos = 0; 312 | memset(input, 0, CLI_BUFFER); 313 | connected = false; 314 | willEcho = true; 315 | prompt = NULL; 316 | _redirect = NULL; 317 | } 318 | 319 | #if (ARDUINO >= 100) 320 | size_t CLIClient::write(uint8_t c) { 321 | #else 322 | void CLIClient::write(uint8_t c) { 323 | #endif 324 | dev->write(c); 325 | #if (ARDUINO > 100) 326 | return 1; 327 | #endif 328 | } 329 | 330 | void CLIClient::setPrompt(const char *p) { 331 | if (prompt != NULL) { 332 | free(prompt); 333 | prompt = NULL; 334 | } 335 | if (p == NULL) { 336 | return; 337 | } 338 | prompt = strdup(p); 339 | } 340 | 341 | void CLIServer::setDefaultPrompt(const char *p) { 342 | if (prompt != NULL) { 343 | free(prompt); 344 | prompt = NULL; 345 | } 346 | if (p == NULL) { 347 | return; 348 | } 349 | prompt = strdup(p); 350 | } 351 | 352 | void CLIClient::printPrompt() { 353 | if (prompt == NULL) { 354 | return; 355 | } 356 | print(prompt); 357 | } 358 | 359 | uint8_t CLIClient::testConnected() { 360 | if (&dev) { 361 | if (!connected) { 362 | connected = true; 363 | return CLIClient::CONNECTED; 364 | } 365 | } else { 366 | if (connected) { 367 | connected = false; 368 | return CLIClient::DISCONNECTED; 369 | } 370 | } 371 | return CLIClient::IDLE; 372 | } 373 | 374 | void CLIServer::onConnect(int (*function)(CLIClient *, int, char **)) { 375 | _onConnect = function; 376 | } 377 | 378 | void CLIServer::onDisconnect(int (*function)(CLIClient *, int, char **)) { 379 | _onDisconnect = function; 380 | } 381 | 382 | 383 | CLIClient::~CLIClient() { 384 | if (prompt) { 385 | free(prompt); 386 | } 387 | } 388 | 389 | void CLIServer::removeClient(CLIClient &c) { 390 | removeClient(&c); 391 | } 392 | 393 | void CLIServer::removeClient(CLIClient *c) { 394 | removeClient(c->dev); 395 | } 396 | 397 | void CLIServer::removeClient(Stream &dev) { 398 | removeClient(&dev); 399 | } 400 | 401 | void CLIServer::removeClient(Stream *dev) { 402 | CLIClientList *scan; 403 | CLIClientList *oldClient; 404 | 405 | if (clients->client->dev == dev) { 406 | oldClient = clients; 407 | clients = oldClient->next; 408 | delete oldClient->client; 409 | free(oldClient); 410 | return; 411 | } 412 | 413 | for (scan = clients; scan->next; scan = scan->next) { 414 | if (scan->next->client->dev == dev) { 415 | oldClient = scan->next; 416 | scan->next = oldClient->next; 417 | delete oldClient->client; 418 | free(oldClient); 419 | return; 420 | } 421 | } 422 | } 423 | -------------------------------------------------------------------------------- /src/CLI.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, Majenko Technologies 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without modification, 6 | * are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright notice, this 9 | * list of conditions and the following disclaimer. 10 | * 11 | * * Redistributions in binary form must reproduce the above copyright notice, this 12 | * list of conditions and the following disclaimer in the documentation and/or 13 | * other materials provided with the distribution. 14 | * 15 | * * Neither the name of Majenko Technologies nor the names of its 16 | * contributors may be used to endorse or promote products derived from 17 | * this software without specific prior written permission. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | #ifndef _CLI_H 32 | #define _CLI_H 33 | 34 | #if ARDUINO >= 100 35 | # include 36 | #else 37 | # include 38 | #endif 39 | 40 | #include 41 | 42 | #define CLI_BUFFER 80 43 | 44 | class CLIServer; 45 | 46 | class CLIClient : public Stream { 47 | private: 48 | Stream *dev; 49 | char input[CLI_BUFFER]; 50 | int pos; 51 | char *prompt; 52 | boolean connected; 53 | 54 | boolean willEcho; 55 | 56 | uint8_t testConnected(); 57 | 58 | void *_sessionData; 59 | 60 | void (*_redirect)(CLIClient *, char *, int); 61 | 62 | 63 | public: 64 | static const uint8_t IDLE = 0; 65 | static const uint8_t CONNECTED = 1; 66 | static const uint8_t DISCONNECTED = 2; 67 | 68 | CLIClient(Stream *d); 69 | virtual ~CLIClient(); 70 | void echo(boolean e) { willEcho = e; } 71 | void printPrompt(); 72 | int readline(); 73 | int parseCommand(); 74 | void setPrompt(const char *p); 75 | void setSessionData(void *data); 76 | void *getSessionData(); 77 | 78 | void redirectStart(void (*func)(CLIClient *, char *, int)) { _redirect = func; } 79 | void redirectEnd() { _redirect = NULL; } 80 | 81 | size_t write(uint8_t); 82 | int available() { return dev->available(); } 83 | int read() { return dev->read(); } 84 | void flush() { dev->flush(); } 85 | int peek() { return dev->peek(); } 86 | 87 | friend class CLIServer; 88 | }; 89 | 90 | #define CLI_COMMAND(X) int X(CLIClient *dev, int argc, char **argv) 91 | 92 | typedef struct _CLIClientList { 93 | CLIClient *client; 94 | struct _CLIClientList *next; 95 | } CLIClientList; 96 | 97 | #define CLI_IS_PREFIX 0x01 98 | 99 | typedef struct _CLICommand { 100 | char *command; 101 | uint8_t flags; 102 | int (*function)(CLIClient *, int, char **); 103 | struct _CLICommand *next; 104 | } CLICommand; 105 | 106 | class CLIServer : public Print { 107 | private: 108 | CLIClientList *clients; 109 | CLICommand *commands; 110 | char *prompt; 111 | boolean _caseSensitive; 112 | 113 | int (*_onConnect)(CLIClient *, int, char **); 114 | int (*_onDisconnect)(CLIClient *, int, char **); 115 | 116 | public: 117 | CLIServer(); 118 | void setCaseInsensitive(); 119 | void setCaseSensitive(); 120 | boolean isCaseSensitive(); 121 | void addCommand(const char *command, int (*function)(CLIClient *, int, char **)); 122 | void addPrefix(const char *command, int (*function)(CLIClient *, int, char **)); 123 | CLIClient *addClient(Stream *dev, void *data); 124 | CLIClient *addClient(Stream &dev, void *data); 125 | CLIClient *addClient(Stream *dev); 126 | CLIClient *addClient(Stream &dev); 127 | void removeClient(CLIClient *c); 128 | void removeClient(CLIClient &c); 129 | void removeClient(Stream *dev); 130 | void removeClient(Stream &dev); 131 | void onConnect(int (*function)(CLIClient *, int, char **)); 132 | void onDisconnect(int (*function)(CLIClient *, int, char **)); 133 | void process(); 134 | void setDefaultPrompt(const char *p); 135 | void broadcast(char *); 136 | #if (ARDUINO >= 100) 137 | size_t write(uint8_t); 138 | #else 139 | void write(uint8_t); 140 | #endif 141 | 142 | friend class CLIClient; 143 | }; 144 | 145 | extern CLIServer CLI; 146 | 147 | #endif 148 | -------------------------------------------------------------------------------- /uecide.json: -------------------------------------------------------------------------------- 1 | {"name":"CLI","provides":"CLI.h","license":"LICENSE","readme":"README.md","description":"Command-line Interface library for Arduino","category":"Communications","subcategory":"Serial","maintainer":"Matt Jenkins ","version":"1.2.6","family":"all","core":"all","install":{"examples":"\/","library.properties":"\/","src":"\/"}} --------------------------------------------------------------------------------