mirror of
https://github.com/tio/tio.git
synced 2026-05-01 14:57:59 +02:00
+ Add system timestamps to lua read() and new lua read_line() per global options; prevented warnings
+ Add missing timestamp-format epoch; update send_ to use fsync and tcdrain like normal tty_sync does; rework read_line to save partial line at timeout
This commit is contained in:
parent
ab678e6c88
commit
e5f9b947c4
13 changed files with 201 additions and 22 deletions
17
examples/lua/lines.lua
Normal file
17
examples/lua/lines.lua
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
read(1000, 8000) -- read initial config
|
||||
send("\n")
|
||||
read(650, 100) -- main menu
|
||||
send("S") -- S menu
|
||||
n = 1
|
||||
while n > 0 do -- while not empty, read more
|
||||
n, str = read_line(25)
|
||||
end
|
||||
while true do
|
||||
send("t") -- query PV table
|
||||
msleep(880)
|
||||
n = 1
|
||||
while n > 0 do -- while not empty, read more
|
||||
n, str = read_line(60)
|
||||
msleep(60)
|
||||
end
|
||||
end
|
||||
14
examples/lua/pts.lua
Normal file
14
examples/lua/pts.lua
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
read(1000, 6000) -- initial config
|
||||
send("\n")
|
||||
msleep(100)
|
||||
read(650, 60) -- main menu
|
||||
send("S") -- S menu
|
||||
msleep(30)
|
||||
read(650, 60)
|
||||
send("t") -- Parallel Value Table
|
||||
read(650, 60)
|
||||
while true do
|
||||
msleep(1000)
|
||||
send("t")
|
||||
read(650, 50) -- repeat PVT forever
|
||||
end
|
||||
16
examples/lua/pvt.lua
Normal file
16
examples/lua/pvt.lua
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
send("\n")
|
||||
msleep(100)
|
||||
-- read buffer with 0.5 sec delay
|
||||
read(160, 500)
|
||||
send("S")
|
||||
msleep(100)
|
||||
-- read buffer
|
||||
read(160, 500)
|
||||
-- query Parallel Value Table
|
||||
send("t")
|
||||
print(read(300, 500))
|
||||
while true do
|
||||
sleep(1)
|
||||
send("t")
|
||||
print(read(300, 500))
|
||||
end
|
||||
13
man/tio.1.in
13
man/tio.1.in
|
|
@ -467,7 +467,18 @@ until data is ready to read.
|
|||
|
||||
Returns number of bytes read on success, 0 on timeout, or -1 on error.
|
||||
|
||||
On success, returns read string as second return value.
|
||||
On success, returns read string as second return value. Also emits a single
|
||||
timestamp to stdout and log file per options.timestamp and options.log.
|
||||
|
||||
.IP "\fBread_line(timeout)"
|
||||
Read line from serial device. If timeout is 0 or not provided it will wait
|
||||
forever until data is ready to read.
|
||||
|
||||
Returns number of bytes read on success, 0 on timeout, or -1 on error.
|
||||
|
||||
On success, returns the string that was read as second return value. Also
|
||||
emits a single timestamp to stdout and log file per options.timestamp
|
||||
and options.log.
|
||||
|
||||
.IP "\fBset{line=state, ...}"
|
||||
Set state of one or multiple tty modem lines.
|
||||
|
|
|
|||
|
|
@ -373,7 +373,14 @@ SCRIPT API
|
|||
|
||||
Returns number of bytes read on success, 0 on timeout, or -1 on error.
|
||||
|
||||
On success, returns read string as second return value.
|
||||
On success, returns read string as second return value. Also emits a single timestamp to stdout and log file per options.timestamp and options.log.
|
||||
|
||||
read_line(timeout)
|
||||
Read line from serial device. If timeout is 0 or not provided it will wait forever until data is ready to read.
|
||||
|
||||
Returns number of bytes read on success, 0 on timeout, or -1 on error.
|
||||
|
||||
On success, returns the string that was read as second return value. Also emits a single timestamp to stdout and log file per options.timestamp and options.log.
|
||||
|
||||
set{line=state, ...}
|
||||
Set state of one or multiple tty modem lines.
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ static void config_parse_keys(GKeyFile *key_file, char *group)
|
|||
{
|
||||
option.timestamp = TIMESTAMP_24HOUR;
|
||||
}
|
||||
config_get_string(key_file, group, "timestamp-format", &string, "24hour", "24hour-start", "24hour-delta", "iso8601", NULL);
|
||||
config_get_string(key_file, group, "timestamp-format", &string, "24hour", "24hour-start", "24hour-delta", "iso8601", "epoch", NULL);
|
||||
if (string != NULL)
|
||||
{
|
||||
option_parse_timestamp(string, &option.timestamp);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define __STDC_WANT_LIB_EXT2__ 1 // To access vasprintf
|
||||
|
||||
#define _GNU_SOURCE // To access vasprintf
|
||||
#include <stdio.h>
|
||||
#include "print.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define __STDC_WANT_LIB_EXT2__ 1 // To access vasprintf
|
||||
|
||||
#define _GNU_SOURCE // To access vasprintf
|
||||
#include <sys/time.h>
|
||||
#include <libgen.h>
|
||||
#include <errno.h>
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
* 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE // To access vasprintf
|
||||
|
||||
#include <assert.h>
|
||||
#include <regex.h>
|
||||
#include <getopt.h>
|
||||
|
|
|
|||
139
src/script.c
139
src/script.c
|
|
@ -37,6 +37,8 @@
|
|||
#include "log.h"
|
||||
#include "script.h"
|
||||
#include "fs.h"
|
||||
#include "timestamp.h"
|
||||
#include "termios.h"
|
||||
|
||||
#define MAX_BUFFER_SIZE 2000 // Maximum size of circular buffer
|
||||
|
||||
|
|
@ -192,6 +194,8 @@ static int send_(lua_State *L)
|
|||
}
|
||||
|
||||
ret = write(device_fd, string, strlen(string));
|
||||
fsync(device_fd); // flush these characters now
|
||||
tcdrain(device_fd); //ensure we flushed characters to our device
|
||||
|
||||
lua_pushnumber(L, ret);
|
||||
|
||||
|
|
@ -248,18 +252,47 @@ static bool match_regex(regex_t *regex)
|
|||
return false;
|
||||
}
|
||||
|
||||
// lua: ret,string = read_string(size, timeout)
|
||||
// Function to echo a buffer to stdout and to the log
|
||||
// per the option.timestamp and option.log settings
|
||||
static void echo_buffer(char buffer[], ssize_t len)
|
||||
{
|
||||
if (option.timestamp)
|
||||
{
|
||||
char *pTimeStampNow;
|
||||
pTimeStampNow = timestamp_current_time();
|
||||
if (pTimeStampNow)
|
||||
{
|
||||
tio_printf("%s", buffer); //does timestamps for us
|
||||
if (option.log)
|
||||
{
|
||||
log_printf("\n[%s] %s", pTimeStampNow, buffer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ssize_t i=0; i<len; i++)
|
||||
{
|
||||
putchar(buffer[i]);
|
||||
|
||||
if (option.log)
|
||||
{
|
||||
log_putc(buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// lua: ret,string = read(size, timeout)
|
||||
static int read_string(lua_State *L)
|
||||
{
|
||||
int size = lua_tointeger(L, 1);
|
||||
int size = lua_tointeger(L, 1) + 1; //plus one for null-terminated string
|
||||
int timeout = lua_tointeger(L, 2);
|
||||
int ret = 0;
|
||||
|
||||
char *buffer = malloc(size);
|
||||
char *buffer = calloc(1, size);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
ret = -1; // Error
|
||||
goto error;
|
||||
goto error_rs;
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
|
|
@ -271,33 +304,112 @@ static int read_string(lua_State *L)
|
|||
if (bytes_read < 0)
|
||||
{
|
||||
ret = -1; // Error
|
||||
goto error;
|
||||
goto error_rs;
|
||||
}
|
||||
else if (bytes_read == 0)
|
||||
{
|
||||
ret = 0; // Timeout
|
||||
goto error;
|
||||
goto error_rs;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[bytes_read] = (char)0;
|
||||
}
|
||||
|
||||
for (ssize_t i=0; i<bytes_read; i++)
|
||||
{
|
||||
putchar(buffer[i]);
|
||||
echo_buffer(&buffer[0], bytes_read);
|
||||
ret = bytes_read;
|
||||
|
||||
if (option.log)
|
||||
error_rs:
|
||||
lua_pushnumber(L, ret);
|
||||
if (buffer != NULL)
|
||||
{
|
||||
lua_pushstring(L, ret > 0 ? buffer : "");
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, ""); // give empty string to caller
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
#define READ_LINE_SIZE 4096 // read_line buffer length
|
||||
|
||||
// lua: ret,string = read_line(timeout)
|
||||
static int read_line(lua_State *L)
|
||||
{
|
||||
int timeout = lua_tointeger(L, 1); //ms
|
||||
int ret = 0;
|
||||
int nl_seen = 0;
|
||||
int read_result = 1; //enable reading input from device
|
||||
char ch;
|
||||
int bytes_read = 0;
|
||||
|
||||
char *buffer = calloc(1, READ_LINE_SIZE);
|
||||
if (buffer == NULL)
|
||||
{
|
||||
ret = -1; // Error
|
||||
read_result = -1; //disable reading input from device
|
||||
}
|
||||
|
||||
if (timeout == 0)
|
||||
{
|
||||
timeout = -1; // Wait forever
|
||||
}
|
||||
|
||||
// loop reading input until a newline seen or timeout
|
||||
while (!nl_seen && (read_result > 0))
|
||||
{
|
||||
read_result = read_poll(device_fd, &ch, 1, timeout);
|
||||
if (read_result < 0)
|
||||
{
|
||||
log_putc(buffer[i]);
|
||||
ret = -1; // Error
|
||||
}
|
||||
else if (!read_result)
|
||||
{
|
||||
// Timeout returns a non-empty buffer as a 'line'
|
||||
if (bytes_read)
|
||||
{
|
||||
nl_seen = 1;
|
||||
ret = bytes_read;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
else // we got a character, so handle it
|
||||
{
|
||||
if (ch == '\n')
|
||||
{
|
||||
nl_seen = 1;
|
||||
}
|
||||
else if (bytes_read <= (READ_LINE_SIZE-2))
|
||||
{
|
||||
if (ch != '\r') // skip pesky control characters
|
||||
{
|
||||
buffer[bytes_read++] = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = bytes_read;
|
||||
if (nl_seen || (read_result > 0))
|
||||
{
|
||||
echo_buffer(&buffer[0], bytes_read);
|
||||
ret = bytes_read;
|
||||
}
|
||||
|
||||
error:
|
||||
lua_pushnumber(L, ret);
|
||||
if (buffer != NULL)
|
||||
{
|
||||
lua_pushstring(L, buffer);
|
||||
free(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushstring(L, ""); // give empty string to caller
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
|
@ -457,6 +569,7 @@ static const struct luaL_Reg tio_lib[] =
|
|||
{ "modem_send", modem_send},
|
||||
{ "send", send_},
|
||||
{ "read", read_string},
|
||||
{ "read_line", read_line},
|
||||
{ "expect", expect},
|
||||
{ "exit", exit_},
|
||||
{ "tty_search", tty_search_},
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
#include "options.h"
|
||||
#include "timestamp.h"
|
||||
|
||||
#define TIME_STRING_SIZE_MAX 24
|
||||
|
||||
char *timestamp_current_time(void)
|
||||
{
|
||||
static char time_string[TIME_STRING_SIZE_MAX];
|
||||
|
|
|
|||
|
|
@ -32,5 +32,7 @@ typedef enum
|
|||
TIMESTAMP_END,
|
||||
} timestamp_t;
|
||||
|
||||
#define TIME_STRING_SIZE_MAX 24
|
||||
|
||||
char *timestamp_current_time(void);
|
||||
|
||||
|
|
|
|||
|
|
@ -1615,6 +1615,7 @@ const char* get_serial_port_type(const char* port_name)
|
|||
|
||||
const char* get_serial_port_type(const char* port_name)
|
||||
{
|
||||
(void)port_name;
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue