diff options
Diffstat (limited to 'astrftime.c')
| -rw-r--r-- | astrftime.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/astrftime.c b/astrftime.c new file mode 100644 index 0000000..4c10654 --- /dev/null +++ b/astrftime.c @@ -0,0 +1,58 @@ +#define _POSIX_C_SOURCE 200809L + +#include "utils.h" +#include <errno.h> +#include <locale.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> + +char *astrftime(const char *const fmt, const struct tm *const tm) +{ + char *ret = NULL, *s = NULL; + size_t n = sizeof "."; + const locale_t l = newlocale(LC_TIME_MASK, "POSIX", (locale_t)0); + + if (l == (locale_t)0) + { + fprintf(stderr, "%s: newlocale(3): %s\n", __func__, strerror(errno)); + goto end; + } + else if (!(s = malloc(n))) + { + fprintf(stderr, "%s: malloc(3): %s\n", __func__, strerror(errno)); + goto end; + } + + for (;;) + { + const int res = strftime_l(s, n, fmt, tm, l); + + if (!res) + { + char *const ss = realloc(s, ++n); + + if (!s) + { + fprintf(stderr, "%s: realloc(3): %s\n", __func__, + strerror(errno)); + goto end; + } + + s = ss; + } + else + break; + } + + ret = s; + +end: + + if (!ret) + free(s); + + freelocale(l); + return ret; +} |
