summaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c192
1 files changed, 137 insertions, 55 deletions
diff --git a/src/main.c b/src/main.c
index 10630e8..0ff76c9 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 @
*
@@ -17,6 +17,12 @@
* along with @. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "config.h"
+
+#ifdef ENABLE_NLS
+#include <locale.h>
+#endif
+
#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
@@ -24,8 +30,8 @@
#include <string.h>
#include <time.h>
#include <unistd.h>
-#include "config.h"
#include "datetime.h"
+#include "i18n.h"
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
#include <getopt.h>
@@ -34,7 +40,7 @@
extern const char *PACKAGE_VERSION_GIT;
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
-struct option LONGOPTS_[] = {
+static const struct option LONGOPTS_[] = {
{
.name = "list-formats",
.has_arg = 0,
@@ -59,63 +65,83 @@ struct option LONGOPTS_[] = {
static void
_print_usage(FILE *stream, const char *program_name)
{
- fprintf(stream, "Usage: %s [date]time\n", program_name);
+ fprintf(stream, _("Usage: %s [date]time\n"), program_name);
}
static void
_print_help(const char *program_name)
{
_print_usage(stdout, program_name);
- puts("Options:");
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
- puts("\t-F, --list-formats List all supported date and time formats");
- puts("\t-h, --help Show this help information");
- puts("\t-V, --version Show version information");
+ puts(_("Options:\n"
+ " -F, --list-formats List all supported date and time formats\n"
+ " -h, --help Show this help information\n"
+ " -V, --version Show version information"));
#else
- puts("\t-F List all supported date and time formats");
- puts("\t-h Show this help information");
- puts("\t-V Show version information");
+ puts(_("Options:\n"
+ " -F List all supported date and time formats\n"
+ " -h Show this help information\n"
+ " -V Show version information"));
#endif
}
-static void
-_list_formats(void)
+#if defined(ENABLE_TESTS) && ENABLE_TESTS
+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;
+ time_t t;
+ struct tm *tm_p;
- tim = time(NULL);
- tm = localtime(&tim);
+ sscanf(buf, "%04d-%02d-%02d %02d:%02d:%02d",
+ &tm.tm_year, &tm.tm_mon, &tm.tm_mday,
+ &tm.tm_hour, &tm.tm_min, &tm.tm_sec);
+ tm.tm_year -= 1900;
+ tm.tm_mon -= 1;
+ tm.tm_wday = -1;
+ tm.tm_yday = -1;
+ tm.tm_isdst = -1;
- puts("Time formats:");
+ t = mktime(&tm);
+ tm_p = localtime(&t);
+
+ return tm_p;
+}
+#endif
+
+static void
+_list_formats(const struct tm *tm)
+{
+ char *out;
+ size_t buf_sz;
+ char *buf;
+ size_t i;
+
+ puts(_("Time formats:"));
i = 0;
while (datetime_strftime_time(tm, &out, &buf_sz, &buf, &i) > 0) {
if (out[0] == '\0') {
continue;
}
- printf(" * %s\n", out);
+ printf(_(" * %s\n"), out);
}
- puts("Date formats:");
+ puts(_("Date formats:"));
i = 0;
while (datetime_strftime_date(tm, &out, &buf_sz, &buf, &i) > 0) {
if (out[0] == '\0') {
continue;
}
- printf(" * %s\n", out);
+ printf(_(" * %s\n"), out);
}
- puts("Additional formats:");
+ puts(_("Additional formats:"));
i = 0;
while (datetime_strftime_misc(tm, &out, &buf_sz, &buf, &i) > 0) {
if (out[0] == '\0') {
continue;
}
- printf(" * %s\n", out);
+ printf(_(" * %s\n"), out);
}
}
@@ -123,13 +149,12 @@ static void
_print_version(void)
{
printf("@ (atsign) %s%s\n", PACKAGE_VERSION, PACKAGE_VERSION_GIT);
- puts("Copyright (C) 2021 P. J. McDermott");
- puts("License GPLv3+: GNU GPL version 3 or later "
- "<http://gnu.org/licenses/gpl.html>.");
- puts("This is free software: you are free to change and redistribute "
- "it.");
- puts("There is NO WARRANTY, to the extent permitted by law.\n");
- printf("Please report bugs to <%s>.\n", PACKAGE_BUGREPORT);
+ puts(_("Copyright (C) 2021, 2022 P. J. McDermott\n"
+ "License GPLv3+: GNU GPL version 3 or later "
+ "<http://gnu.org/licenses/gpl.html>.\n"
+ "This is free software: you are free to change and redistribute it.\n"
+ "There is NO WARRANTY, to the extent permitted by law.\n"));
+ printf(_("Please report bugs to <%s>.\n"), PACKAGE_BUGREPORT);
}
static char *
@@ -148,7 +173,7 @@ _concat_args(int argc, char * const argv[])
buf = calloc(buf_l, sizeof(*buf));
if (buf == NULL) {
- fprintf(stderr, "Failed to allocate buffer: %s\n",
+ fprintf(stderr, _("Failed to allocate buffer: %s\n"),
strerror(errno));
return NULL;
}
@@ -168,37 +193,76 @@ _concat_args(int argc, char * const argv[])
int
main(int argc, char * const argv[])
{
- int opt;
- char *buf;
- time_t arg;
- time_t now;
- time_t dif;
+#if defined(ENABLE_TESTS) && ENABLE_TESTS
+ bool dbg;
+#endif
+ bool fmt;
+ int opt;
+ char *buf;
+ time_t now;
+ struct tm *now_tm;
+ struct tm arg_tm;
+ time_t arg;
+ double dif;
+#ifdef ENABLE_NLS
+ bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+ bind_textdomain_codeset(PACKAGE, "UTF-8");
+#endif
+ textdomain(PACKAGE);
+ setlocale(LC_ALL, "");
+#endif
+
+#if defined(ENABLE_TESTS) && ENABLE_TESTS
+ dbg = false;
+#endif
+ fmt = false;
optind = 1;
opterr = 0;
+ now = time(NULL);
+ now_tm = localtime(&now);
+
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
- while ((opt = getopt_long(argc, argv, "FhV", LONGOPTS_, NULL)) > 0) {
+#if defined(ENABLE_TESTS) && ENABLE_TESTS
+ while ((opt = getopt_long(argc, argv, "FhVd:", LONGOPTS_, NULL)) > 0) {
+#else
+ while ((opt = getopt_long(argc, argv, "FhV:", LONGOPTS_, NULL)) > 0) {
+#endif
+#else
+#if defined(ENABLE_TESTS) && ENABLE_TESTS
+ while ((opt = getopt(argc, argv, "FhVd:")) > 0) {
#else
- while ((opt = getopt(argc, argv, "FhV")) > 0) {
+ while ((opt = getopt(argc, argv, "FhV:")) > 0) {
+#endif
#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;
+#if defined(ENABLE_TESTS) && ENABLE_TESTS
+ case 'd':
+ dbg = true;
+ now_tm = _set_now(optarg);
+ if (now_tm == NULL) {
+ return EXIT_FAILURE;
+ }
+ break;
+#endif
default:
_print_usage(stderr, argv[0]);
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
- fprintf(stderr, "Try '%s --help' for more "
- "information.\n", argv[0]);
+ fprintf(stderr, _("Try '%s --help' for more "
+ "information.\n"), argv[0]);
#else
- fprintf(stderr, "Try '%s -h' for more "
- "information.\n", argv[0]);
+ fprintf(stderr, _("Try '%s -h' for more "
+ "information.\n"), argv[0]);
#endif
return EXIT_FAILURE;
}
@@ -206,34 +270,52 @@ main(int argc, char * const argv[])
argc -= optind;
argv += optind;
+ 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_tm, &arg) < 0) {
free(buf);
return EXIT_FAILURE;
}
free(buf);
- time(&now);
- dif = arg - now;
+#if defined(ENABLE_TESTS) && ENABLE_TESTS
+ if (dbg == true) {
+ printf("%04d-%02d-%02d %02d:%02d:%02d\n",
+ arg_tm.tm_year + 1900,
+ arg_tm.tm_mon + 1,
+ arg_tm.tm_mday,
+ arg_tm.tm_hour,
+ arg_tm.tm_min,
+ arg_tm.tm_sec);
+ return EXIT_SUCCESS;
+ }
+#endif
+
+ now = time(NULL);
+ dif = difftime(arg, now);
if (dif >= 1000 * 24 * 60 * 60) {
- fputs("Date too far in the future\n", stderr);
+ fputs(_("Date too far in the future\n"), stderr);
return EXIT_FAILURE;
}
setvbuf(stdout, NULL, _IONBF, 0);
- while (arg > now) {
+ while (dif > 0) {
printf("\r%03d:%02d:%02d:%02d",
(int) dif / 60 / 60 / 24,
(int) dif / 60 / 60 % 24,
(int) dif / 60 % 60,
(int) dif % 60);
sleep(1);
- time(&now);
- dif = arg - now;
+ now = time(NULL);
+ dif = difftime(arg, now);
}
printf("\r000:00:00:00\n");