Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007 #include <FastSerial.h>
00008 #include <AP_Common.h>
00009
00010 #include <ctype.h>
00011 #include <string.h>
00012 #include <avr/pgmspace.h>
00013
00014 #include "include/menu.h"
00015
00016
00017 char Menu::_inbuf[MENU_COMMANDLINE_MAX];
00018 Menu::arg Menu::_argv[MENU_ARGS_MAX + 1];
00019
00020
00021 Menu::Menu(const prog_char *prompt, const Menu::command *commands, uint8_t entries, preprompt ppfunc) :
00022 _prompt(prompt),
00023 _commands(commands),
00024 _entries(entries),
00025 _ppfunc(ppfunc)
00026 {
00027 }
00028
00029
00030 void
00031 Menu::run(void)
00032 {
00033 uint8_t len, i, ret;
00034 uint8_t argc;
00035 int c;
00036 char *s;
00037
00038
00039 for (;;) {
00040
00041
00042 if ((NULL != _ppfunc) && !_ppfunc())
00043 return;
00044
00045
00046 len = 0;
00047 Serial.printf("%S] ", _prompt);
00048 for (;;) {
00049 c = Serial.read();
00050 if (-1 == c)
00051 continue;
00052
00053 if ('\r' == c) {
00054 _inbuf[len] = '\0';
00055 Serial.write('\r');
00056 Serial.write('\n');
00057 break;
00058 }
00059
00060 if ('\b' == c) {
00061 if (len > 0) {
00062 len--;
00063 Serial.write('\b');
00064 Serial.write(' ');
00065 Serial.write('\b');
00066 continue;
00067 }
00068 }
00069
00070 if (isprint(c) && (len < (MENU_COMMANDLINE_MAX - 1))) {
00071 _inbuf[len++] = c;
00072 Serial.write((char)c);
00073 continue;
00074 }
00075 }
00076
00077
00078 argc = 0;
00079 _argv[argc++].str = strtok_r(_inbuf, " ", &s);
00080
00081 while (argc <= MENU_ARGS_MAX) {
00082 _argv[argc].str = strtok_r(NULL, " ", &s);
00083 if ('\0' == _argv[argc].str)
00084 break;
00085 _argv[argc].i = atol(_argv[argc].str);
00086 _argv[argc].f = atof(_argv[argc].str);
00087 argc++;
00088 }
00089
00090
00091
00092
00093 i = argc;
00094 while (i <= MENU_ARGS_MAX) {
00095 _argv[i].str = "";
00096 _argv[i].i = 0;
00097 _argv[i].f = 0;
00098 i++;
00099 }
00100
00101
00102 for (i = 0; i < _entries; i++) {
00103 if (!strcasecmp_P(_argv[0].str, _commands[i].command)) {
00104 ret = _call(i, argc);
00105 if (-2 == ret)
00106 return;
00107 break;
00108 }
00109 }
00110
00111
00112 if (i == _entries) {
00113 if (!strcmp(_argv[0].str, "?") || (!strcasecmp_P(_argv[0].str, PSTR("help")))) {
00114 _help();
00115 } else if (!strcasecmp_P(_argv[0].str, PSTR("exit"))) {
00116 return;
00117 }
00118 }
00119 }
00120 }
00121
00122
00123 void
00124 Menu::_help(void)
00125 {
00126 int i;
00127
00128 Serial.println("Commands:");
00129 for (i = 0; i < _entries; i++)
00130 Serial.printf(" %S\n", _commands[i].command);
00131 }
00132
00133
00134 int8_t
00135 Menu::_call(uint8_t n, uint8_t argc)
00136 {
00137 func fn;
00138
00139 fn = (func)pgm_read_word(&_commands[n].func);
00140 return(fn(argc, &_argv[0]));
00141 }