diff --git a/Grbl_Esp32/src/ProcessSettings.cpp b/Grbl_Esp32/src/ProcessSettings.cpp index a6831713..a04ca4df 100644 --- a/Grbl_Esp32/src/ProcessSettings.cpp +++ b/Grbl_Esp32/src/ProcessSettings.cpp @@ -1,5 +1,6 @@ #include "Grbl.h" #include +#include "Regex.h" // WG Readable and writable as guest // WU Readable and writable as user and admin @@ -565,19 +566,13 @@ Error do_command_or_setting(const char* key, char* value, WebUI::AuthenticationL Error retval = Error::InvalidStatement; if (!value) { auto lcKey = String(key); - // We allow the key string to begin with *, which we remove. - // This lets us look at X axis settings with $*x. - // $x by itself is the disable alarm lock command - if (lcKey.startsWith("*")) { - lcKey.remove(0, 1); - } lcKey.toLowerCase(); bool found = false; for (Setting* s = Setting::List; s; s = s->next()) { auto lcTest = String(s->getName()); lcTest.toLowerCase(); - if (lcTest.indexOf(lcKey) >= 0) { + if (regexMatch(lcKey.c_str(), lcTest.c_str())) { const char* displayValue = auth_failed(s, value, auth_level) ? "" : s->getStringValue(); show_setting(s->getName(), displayValue, NULL, out); found = true; diff --git a/Grbl_Esp32/src/Regex.cpp b/Grbl_Esp32/src/Regex.cpp new file mode 100644 index 00000000..7f942ccc --- /dev/null +++ b/Grbl_Esp32/src/Regex.cpp @@ -0,0 +1,60 @@ +// Simple regular expression matcher from Rob Pike per +// https://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html + +// c matches any literal character c +// ^ matches the beginning of the input string +// $ matches the end of the input string +// * matches zero or more occurrences of any character + +// The code therein has been reformatted into the style used in this +// project while replacing ints used as flags by bools. The regex +// syntax was changed by omitting '.' and making '*' equivalent to +// ".*". This regular expression matcher is for matching setting +// names, where arbitrary repetion of literal characters is +// unlikely. Literal character repetition is most useful for +// skipping whitespace, which does not occur in setting names. The +// "bare * wildcard" is similar to filename wildcarding in many shells +// and CLIs. + +static bool matchHere(const char* regexp, const char* text); + +// matchStar - search for *regexp at beginning of text +static bool matchStar(const char* regexp, const char* text) { + do { + if (matchHere(regexp, text)) { + return true; + } + } while (*text++ != '\0'); + return false; +} + +// matchHere - search for regex at beginning of text +static bool matchHere(const char* regexp, const char* text) { + if (regexp[0] == '\0') { + return true; + } + if (regexp[0] == '*') { + return matchStar(regexp + 1, text); + } + if (regexp[0] == '$' && regexp[1] == '\0') { + return *text == '\0'; + } + if (*text != '\0' && (regexp[0] == *text)) { + return matchHere(++regexp, ++text); + } + return false; +} + +// match - search for regular expression anywhere in text +// Returns true if text contains the regular expression regexp +bool regexMatch(const char* regexp, const char* text) { + if (regexp[0] == '^') { + return matchHere(++regexp, text); + } + do { + if (matchHere(regexp, text)) { + return true; + } + } while (*text++ != '\0'); + return false; +} diff --git a/Grbl_Esp32/src/Regex.h b/Grbl_Esp32/src/Regex.h new file mode 100644 index 00000000..9c0c5d13 --- /dev/null +++ b/Grbl_Esp32/src/Regex.h @@ -0,0 +1,5 @@ +// Simple regular expression matcher. +// See Regex.cpp for attribution, description and discussion + +// Returns true if text contains the regular expression regexp +bool regexMatch(const char* regexp, const char* text);