summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorP. J. McDermott <pj@pehjota.net>2022-03-19 19:57:05 (EDT)
committer P. J. McDermott <pj@pehjota.net>2022-03-19 19:57:05 (EDT)
commit004891c1800b77f8a1e84030b42b100484bae8a0 (patch)
tree77a333766249698843fabf57f920d8e12e44d9f6 /src
parent989a30e669b3a4fc3b25a5b3b5d39baf4e76bd7c (diff)
parent44cb41b8995b30c6b2754f3e1182cfdefc6c7b7b (diff)
downloadatsign-004891c1800b77f8a1e84030b42b100484bae8a0.zip
atsign-004891c1800b77f8a1e84030b42b100484bae8a0.tar.gz
atsign-004891c1800b77f8a1e84030b42b100484bae8a0.tar.bz2
Merge branch 'feature/tests'
Diffstat (limited to 'src')
-rw-r--r--src/datetime.c20
-rw-r--r--src/datetime.h2
-rw-r--r--src/main.c118
3 files changed, 104 insertions, 36 deletions
diff --git a/src/datetime.c b/src/datetime.c
index 7c5dcfa..230a348 100644
--- a/src/datetime.c
+++ b/src/datetime.c
@@ -116,19 +116,15 @@ _datetime_reset_tm(struct tm *tm)
}
static void
-_datetime_normalize(struct tm *arg_tm, time_t *arg_sec)
+_datetime_normalize(struct tm *now_tm, struct tm *arg_tm, time_t *arg_sec)
{
- time_t now_sec;
- struct tm *now_tm;
- int wday;
+ int wday;
if (arg_tm->tm_sec == INT_MIN) {
arg_tm->tm_sec = 0;
}
if (arg_tm->tm_mday == INT_MIN && arg_tm->tm_wday == INT_MIN) {
/* No date specified; try today. */
- now_sec = time(NULL);
- now_tm = localtime(&now_sec);
arg_tm->tm_year = now_tm->tm_year;
arg_tm->tm_mon = now_tm->tm_mon;
arg_tm->tm_mday = now_tm->tm_mday;
@@ -150,8 +146,6 @@ _datetime_normalize(struct tm *arg_tm, time_t *arg_sec)
/* Only a weekday specified; try tomorrow or next week. Uses
* same shortcut as above. */
wday = arg_tm->tm_wday;
- now_sec = time(NULL);
- now_tm = localtime(&now_sec);
arg_tm->tm_year = now_tm->tm_year;
arg_tm->tm_mon = now_tm->tm_mon;
arg_tm->tm_mday = now_tm->tm_mday;
@@ -163,8 +157,6 @@ _datetime_normalize(struct tm *arg_tm, time_t *arg_sec)
*arg_sec += (60 * 60 * 24) * (wday - now_tm->tm_wday);
} else if (arg_tm->tm_year == INT_MIN) {
/* No year specified; try this year. */
- now_sec = time(NULL);
- now_tm = localtime(&now_sec);
arg_tm->tm_year = now_tm->tm_year;
*arg_sec = mktime(arg_tm);
if (*arg_sec <= mktime(now_tm)) {
@@ -179,7 +171,7 @@ _datetime_normalize(struct tm *arg_tm, time_t *arg_sec)
}
int
-datetime_parse(const char *input, time_t *arg_sec)
+datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec)
{
int date_fmt_len;
int time_fmt_len;
@@ -219,7 +211,7 @@ datetime_parse(const char *input, time_t *arg_sec)
end = strptime(input, fmt_buf, &arg_tm);
if (end != NULL && *end == '\0') {
free(fmt_buf);
- _datetime_normalize(&arg_tm, arg_sec);
+ _datetime_normalize(now_tm, &arg_tm, arg_sec);
return 0;
}
}
@@ -235,7 +227,7 @@ datetime_parse(const char *input, time_t *arg_sec)
end = strptime(input, fmt_buf, &arg_tm);
if (end != NULL && *end == '\0') {
free(fmt_buf);
- _datetime_normalize(&arg_tm, arg_sec);
+ _datetime_normalize(now_tm, &arg_tm, arg_sec);
return 0;
}
}
@@ -246,7 +238,7 @@ datetime_parse(const char *input, time_t *arg_sec)
end = strptime(input, DATETIME_MISC_FMTS_[d], &arg_tm);
if (end != NULL && *end == '\0') {
free(fmt_buf);
- _datetime_normalize(&arg_tm, arg_sec);
+ _datetime_normalize(now_tm, &arg_tm, arg_sec);
return 0;
}
}
diff --git a/src/datetime.h b/src/datetime.h
index edff8f7..554748b 100644
--- a/src/datetime.h
+++ b/src/datetime.h
@@ -23,7 +23,7 @@
#include <time.h>
int
-datetime_parse(const char *input, time_t *arg_sec);
+datetime_parse(struct tm *now_tm, const char *input, time_t *arg_sec);
int
datetime_strftime_date(const struct tm *tm, char **out, size_t *out_sz,
diff --git a/src/main.c b/src/main.c
index bb4abb5..ff6c15c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2021 P. J. McDermott
+ * Copyright (C) 2021, 2022 P. J. McDermott
*
* This file is part of @
*
@@ -18,6 +18,7 @@
*/
#include <errno.h>
+#include <inttypes.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -56,6 +57,18 @@ static const struct option LONGOPTS_[] = {
};
#endif
+static struct tm EPOCH_ = {
+ .tm_sec = 0,
+ .tm_min = 0,
+ .tm_hour = 0,
+ .tm_mday = 1,
+ .tm_mon = 0,
+ .tm_year = 70,
+ .tm_wday = 4,
+ .tm_yday = 0,
+ .tm_isdst = -1,
+};
+
static void
_print_usage(FILE *stream, const char *program_name)
{
@@ -78,18 +91,52 @@ _print_help(const char *program_name)
#endif
}
-static void
-_list_formats(void)
+static struct tm *
+_set_now(char buf[])
{
- time_t tim;
- struct tm *tm;
- char *out;
- size_t buf_sz;
- char *buf;
- size_t i;
+ struct tm tm;
+ char *endptr;
+ time_t t;
+ struct tm *tm_p;
- tim = time(NULL);
- tm = localtime(&tim);
+ if (strlen(buf) != 19) {
+ return NULL;
+ }
+ if (buf[4] != '-' || buf[7] != '-' || buf[10] != ' ' ||
+ buf[13] != ':' || buf[16] != ':') {
+ return NULL;
+ }
+ buf[4] = '\0', buf[7] = '\0', buf[10] = '\0';
+ buf[13] = '\0', buf[16] = '\0';
+ tm.tm_sec = strtol(buf + 17, &endptr, 10);
+ if (endptr[0] != '\0') { return NULL; }
+ tm.tm_min = strtol(buf + 14, &endptr, 10);
+ if (endptr[0] != '\0') { return NULL; }
+ tm.tm_hour = strtol(buf + 11, &endptr, 10);
+ if (endptr[0] != '\0') { return NULL; }
+ tm.tm_mday = strtol(buf + 8, &endptr, 10);
+ if (endptr[0] != '\0') { return NULL; }
+ tm.tm_mon = strtol(buf + 5, &endptr, 10) - 1;
+ if (endptr[0] != '\0') { return NULL; }
+ tm.tm_year = strtol(buf + 0, &endptr, 10) - 1900;
+ if (endptr[0] != '\0') { return NULL; }
+ tm.tm_wday = -1;
+ tm.tm_yday = -1;
+ tm.tm_isdst = -1;
+
+ t = mktime(&tm);
+ tm_p = localtime(&t);
+
+ return tm_p;
+}
+
+static void
+_list_formats(const struct tm *tm)
+{
+ char *out;
+ size_t buf_sz;
+ char *buf;
+ size_t i;
puts("Time formats:");
i = 0;
@@ -168,29 +215,41 @@ _concat_args(int argc, char * const argv[])
int
main(int argc, char * const argv[])
{
- int opt;
- char *buf;
- time_t arg;
- time_t now;
- double dif;
+ bool dbg;
+ bool fmt;
+ int opt;
+ char *buf;
+ time_t now;
+ struct tm *now_tm;
+ time_t arg;
+ double dif;
+ dbg = false;
+ fmt = false;
optind = 1;
opterr = 0;
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
- while ((opt = getopt_long(argc, argv, "FhV", LONGOPTS_, NULL)) > 0) {
+ while ((opt = getopt_long(argc, argv, "FhVd:", LONGOPTS_, NULL)) > 0) {
#else
- while ((opt = getopt(argc, argv, "FhV")) > 0) {
+ while ((opt = getopt(argc, argv, "FhVd:")) > 0) {
#endif
switch (opt) {
case 'F':
- _list_formats();
- return EXIT_SUCCESS;
+ fmt = true;
+ break;
case 'h':
_print_help(argv[0]);
return EXIT_SUCCESS;
case 'V':
_print_version();
return EXIT_SUCCESS;
+ case 'd':
+ dbg = true;
+ now_tm = _set_now(optarg);
+ if (now_tm == NULL) {
+ return EXIT_FAILURE;
+ }
+ break;
default:
_print_usage(stderr, argv[0]);
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
@@ -206,17 +265,34 @@ main(int argc, char * const argv[])
argc -= optind;
argv += optind;
+ if (dbg == false) {
+ now = time(NULL);
+ now_tm = localtime(&now);
+ }
+
+ if (fmt == true) {
+ _list_formats(now_tm);
+ return EXIT_SUCCESS;
+ }
+
buf = _concat_args(argc, argv);
if (buf == NULL) {
return EXIT_FAILURE;
}
- if (datetime_parse(buf, &arg) < 0) {
+ if (datetime_parse(now_tm, buf, &arg) < 0) {
free(buf);
return EXIT_FAILURE;
}
free(buf);
+ if (dbg == true) {
+ now = timegm(&EPOCH_);
+ dif = difftime(arg, now);
+ printf("%" PRId64 "\n", (int64_t) dif);
+ return EXIT_SUCCESS;
+ }
+
time(&now);
dif = difftime(arg, now);
if (dif >= 1000 * 24 * 60 * 60) {