Add timespec_{read,write}_file() and unit tests
This commit is contained in:
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "mgos.h"
|
#include "mgos.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
/* A simple time specifier for windows of time throughout a 24 hour day.
|
/* A simple time specifier for windows of time throughout a 24 hour day.
|
||||||
*
|
*
|
||||||
@ -47,3 +48,7 @@ bool timespec_clear_spec(struct mgos_timespec *ts);
|
|||||||
bool timespec_get_spec(struct mgos_timespec *ts, char *ret, int retlen);
|
bool timespec_get_spec(struct mgos_timespec *ts, char *ret, int retlen);
|
||||||
bool timespec_match(const struct mgos_timespec *ts, const struct tm *tm);
|
bool timespec_match(const struct mgos_timespec *ts, const struct tm *tm);
|
||||||
bool timespec_match_now(const struct mgos_timespec *ts);
|
bool timespec_match_now(const struct mgos_timespec *ts);
|
||||||
|
|
||||||
|
// File IO -- read or write the current timespec to a file
|
||||||
|
bool timespec_write_file(struct mgos_timespec *ts, const char *fn);
|
||||||
|
bool timespec_read_file(struct mgos_timespec *ts, const char *fn);
|
||||||
|
BIN
src/.timespec.c.swp
Normal file
BIN
src/.timespec.c.swp
Normal file
Binary file not shown.
@ -250,3 +250,83 @@ bool timespec_get_spec(struct mgos_timespec *ts, char *ret, int retlen) {
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool timespec_write_file(struct mgos_timespec *ts, const char *fn) {
|
||||||
|
char buf[500];
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if (!timespec_get_spec(ts, buf, sizeof(buf))) {
|
||||||
|
LOG(LL_ERROR, ("Could not convert timespec to string"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fd = open(fn, O_RDWR | O_CREAT | O_TRUNC))) {
|
||||||
|
LOG(LL_ERROR, ("Could not open %s for writing", fn));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((uint32_t)strlen(buf) != (uint32_t)write(fd, buf, strlen(buf))) {
|
||||||
|
LOG(LL_ERROR, ("Short write on %s for data '%s'", fn, buf));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool timespec_read_file(struct mgos_timespec *ts, const char *fn) {
|
||||||
|
int fd;
|
||||||
|
char * buf;
|
||||||
|
char * spec;
|
||||||
|
char * buf_ptr;
|
||||||
|
struct stat fp_stat;
|
||||||
|
|
||||||
|
if (!ts) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fn) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (0 != stat(fn, &fp_stat)) {
|
||||||
|
LOG(LL_ERROR, ("Could not stat %s", fn));
|
||||||
|
}
|
||||||
|
if (fp_stat.st_size > 1024) {
|
||||||
|
LOG(LL_ERROR, ("File size of %s is larger than 1024 bytes (%u)", fn, (uint32_t)fp_stat.st_size));
|
||||||
|
}
|
||||||
|
buf = malloc(fp_stat.st_size + 1);
|
||||||
|
if (!buf) {
|
||||||
|
LOG(LL_ERROR, ("Could not malloc %u bytes for file %s", (uint32_t)fp_stat.st_size, fn));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fd = open(fn, O_RDONLY))) {
|
||||||
|
LOG(LL_ERROR, ("Could not open %s for reading", fn));
|
||||||
|
free(buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (fp_stat.st_size != read(fd, buf, fp_stat.st_size)) {
|
||||||
|
LOG(LL_ERROR, ("Could not read %u bytes from %s", (uint32_t)fp_stat.st_size, fn));
|
||||||
|
close(fd);
|
||||||
|
free(buf);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
buf[fp_stat.st_size] = '\0';
|
||||||
|
close(fd);
|
||||||
|
LOG(LL_INFO, ("buf='%s'", buf));
|
||||||
|
|
||||||
|
// Wipe the timespec and parse back
|
||||||
|
timespec_clear_spec(ts);
|
||||||
|
|
||||||
|
buf_ptr = buf;
|
||||||
|
while ((spec = strtok_r(buf_ptr, ",", &buf_ptr))) {
|
||||||
|
if (!timespec_add_spec(ts, spec)) {
|
||||||
|
LOG(LL_WARN, ("Could not add spec '%s'", spec));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(buf);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -89,6 +89,13 @@ static void test_timespec_state(void) {
|
|||||||
struct mgos_timespec *ts = timespec_create();
|
struct mgos_timespec *ts = timespec_create();
|
||||||
struct tm target;
|
struct tm target;
|
||||||
char buf[500];
|
char buf[500];
|
||||||
|
char tmp_file[30];
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
snprintf (tmp_file, sizeof(tmp_file)-1, "/tmp/timespec_XXXXXX");
|
||||||
|
fd = mkstemp(tmp_file);
|
||||||
|
close(fd);
|
||||||
|
LOG(LL_INFO, ("Temporary filename: %s", tmp_file));
|
||||||
|
|
||||||
ASSERT(ts, "Created timespec");
|
ASSERT(ts, "Created timespec");
|
||||||
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
||||||
@ -157,7 +164,11 @@ static void test_timespec_state(void) {
|
|||||||
// Test timespec retrieval
|
// Test timespec retrieval
|
||||||
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
||||||
ASSERT(0 == strcmp(buf, "23:01:02-01:02:03,14:11:05-14:59:52,12:00:00-13:00:00,08:00:00-10:00:00"), "timespec_get_spec() didn't match input spec(s)");
|
ASSERT(0 == strcmp(buf, "23:01:02-01:02:03,14:11:05-14:59:52,12:00:00-13:00:00,08:00:00-10:00:00"), "timespec_get_spec() didn't match input spec(s)");
|
||||||
LOG(LL_INFO, ("Spec: '%s'", buf));
|
|
||||||
|
// Write to file and read back
|
||||||
|
ASSERT(timespec_write_file(ts, tmp_file), "Could not write timespec to file");
|
||||||
|
ASSERT(timespec_read_file(ts, tmp_file), "Could not read timespec from file");
|
||||||
|
ASSERT(0 == strcmp(buf, "23:01:02-01:02:03,14:11:05-14:59:52,12:00:00-13:00:00,08:00:00-10:00:00"), "timespec_read_file() didn't match input spec(s)");
|
||||||
|
|
||||||
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
|
||||||
@ -187,6 +198,11 @@ static void test_timespec_state(void) {
|
|||||||
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
||||||
ASSERT(0 == strcmp(buf, "03:02:03-04:03:04,02:00:00-02:00:01,23:00:00-01:00:00,00:00:00-00:00:00,08:00:00-10:00:00"), "timespec_get_spec() didn't match input spec(s)");
|
ASSERT(0 == strcmp(buf, "03:02:03-04:03:04,02:00:00-02:00:01,23:00:00-01:00:00,00:00:00-00:00:00,08:00:00-10:00:00"), "timespec_get_spec() didn't match input spec(s)");
|
||||||
|
|
||||||
|
// Write to file and read back
|
||||||
|
ASSERT(timespec_write_file(ts, tmp_file), "Could not write timespec to file");
|
||||||
|
ASSERT(timespec_read_file(ts, tmp_file), "Could not read timespec from file");
|
||||||
|
ASSERT(0 == strcmp(buf, "03:02:03-04:03:04,02:00:00-02:00:01,23:00:00-01:00:00,00:00:00-00:00:00,08:00:00-10:00:00"), "timespec_read_file() didn't match input spec(s)");
|
||||||
|
|
||||||
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
|
||||||
// Some other time counting tests
|
// Some other time counting tests
|
||||||
@ -201,7 +217,15 @@ static void test_timespec_state(void) {
|
|||||||
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
timespec_get_spec(ts, buf, sizeof(buf)-1);
|
||||||
ASSERT(0 == strcmp(buf, "12:00:00-00:00:00,00:00:00-12:00:00"), "timespec_get_spec() didn't match input spec(s)");
|
ASSERT(0 == strcmp(buf, "12:00:00-00:00:00,00:00:00-12:00:00"), "timespec_get_spec() didn't match input spec(s)");
|
||||||
|
|
||||||
|
// Write to file and read back
|
||||||
|
ASSERT(timespec_write_file(ts, tmp_file), "Could not write timespec to file");
|
||||||
|
ASSERT(timespec_read_file(ts, tmp_file), "Could not read timespec from file");
|
||||||
|
ASSERT(0 == strcmp(buf, "12:00:00-00:00:00,00:00:00-12:00:00"), "timespec_read_file() didn't match input spec(s)");
|
||||||
|
|
||||||
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
ASSERT(timespec_destroy(&ts), "Destroyed timespec");
|
||||||
|
|
||||||
|
LOG(LL_INFO, ("Removing temporary file: %s", tmp_file));
|
||||||
|
unlink(tmp_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_timespec() {
|
void test_timespec() {
|
||||||
|
Reference in New Issue
Block a user