Extend lua expect() to also return matched string

This commit is contained in:
Martin Lund 2024-04-17 23:38:18 +02:00
parent 48c9e8a9a9
commit 3cc2d90fda
2 changed files with 18 additions and 2 deletions

View file

@ -375,6 +375,11 @@ In addition to the Lua API tio makes the following functions available:
Expect string - waits for string to match or timeout before continueing. Expect string - waits for string to match or timeout before continueing.
Supports regular expressions. Special characters must be escaped with '\\\\'. Supports regular expressions. Special characters must be escaped with '\\\\'.
Timeout is in milliseconds, defaults to 0 meaning it will wait forever. Timeout is in milliseconds, defaults to 0 meaning it will wait forever.
Returns 1 on successful match, 0 on timeout, or -1 on invalid regular expression.
On successful match it also returns the match string as second return value.
.IP "\fBsend(string)" .IP "\fBsend(string)"
Send string. Send string.
.IP "\fBmodem_send(file, protocol)" .IP "\fBmodem_send(file, protocol)"

View file

@ -39,6 +39,7 @@
static int device_fd; static int device_fd;
static char circular_buffer[MAX_BUFFER_SIZE]; static char circular_buffer[MAX_BUFFER_SIZE];
static char match_string[MAX_BUFFER_SIZE];
static int buffer_size = 0; static int buffer_size = 0;
// lua: sleep(seconds) // lua: sleep(seconds)
@ -233,14 +234,22 @@ void add_to_buffer(char c)
bool match_regex(regex_t *regex) bool match_regex(regex_t *regex)
{ {
char buffer[MAX_BUFFER_SIZE + 1]; // Temporary buffer for regex matching char buffer[MAX_BUFFER_SIZE + 1]; // Temporary buffer for regex matching
const char *s = circular_buffer;
regmatch_t pmatch[1];
regoff_t len;
memcpy(buffer, circular_buffer, buffer_size); memcpy(buffer, circular_buffer, buffer_size);
buffer[buffer_size] = '\0'; // Null-terminate the buffer buffer[buffer_size] = '\0'; // Null-terminate the buffer
// Match against the regex // Match against the regex
int ret = regexec(regex, buffer, 0, NULL, 0); int ret = regexec(regex, buffer, 1, pmatch, 0);
if (!ret) if (!ret)
{ {
// Match found // Match found
len = pmatch[0].rm_eo - pmatch[0].rm_so;
memcpy(match_string, s + pmatch[0].rm_so, len);
match_string[len] = '\0';
return true; return true;
} }
else if (ret == REG_NOMATCH) else if (ret == REG_NOMATCH)
@ -267,6 +276,7 @@ static int expect(lua_State *L)
// Resets buffer to ignore previous `expect` calls // Resets buffer to ignore previous `expect` calls
buffer_size = 0; buffer_size = 0;
match_string[0] = '\0';
if ((string == NULL) || (timeout < 0)) if ((string == NULL) || (timeout < 0))
{ {
@ -316,7 +326,8 @@ static int expect(lua_State *L)
error: error:
lua_pushnumber(L, ret); lua_pushnumber(L, ret);
return 1; lua_pushstring(L, match_string);
return 2;
} }
// lua: exit(code) // lua: exit(code)