From 0c1bb7d7b3d4e9a91ae33455ab761d7e9405c2df Mon Sep 17 00:00:00 2001 From: Shilpa Singh Date: Mon, 9 Nov 2015 12:42:48 -0800 Subject: [PATCH] eina: add API eina_strftime Summary: Add new API eina_strftime API in eina_str @feature Test Plan: test case and example also updated Reviewers: tasn, cedric Reviewed By: cedric Subscribers: cedric Differential Revision: https://phab.enlightenment.org/D3148 Signed-off-by: Cedric BAIL --- AUTHORS | 1 + src/examples/eina/eina_str_01.c | 11 ++++++++++- src/lib/eina/eina_str.c | 33 +++++++++++++++++++++++++++++++++ src/lib/eina/eina_str.h | 26 ++++++++++++++++++++++++++ src/tests/eina/eina_test_str.c | 19 +++++++++++++++++++ 5 files changed, 89 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index eab2011b7a..f714c39aad 100644 --- a/AUTHORS +++ b/AUTHORS @@ -53,6 +53,7 @@ ChunEon Park (Hermet) Rajeev Ranjan (Rajeev) Subodh Kumar Michelle Legrand +Shilpa Singh Eet --- diff --git a/src/examples/eina/eina_str_01.c b/src/examples/eina/eina_str_01.c index 25fe75a6b8..fbe2cf0815 100644 --- a/src/examples/eina/eina_str_01.c +++ b/src/examples/eina/eina_str_01.c @@ -14,6 +14,9 @@ int main(int argc EINA_UNUSED, char **argv EINA_UNUSED) char *part2 = "There are many copies. And they have a plan."; char **arr; int i; + char *time_arr; + time_t curr_time; + struct tm *info; eina_init(); @@ -58,7 +61,13 @@ int main(int argc EINA_UNUSED, char **argv EINA_UNUSED) eina_strlcat(str, "humans", 14); printf("%s\n", str); free(str); - + + curr_time = time(NULL); + info = localtime(&curr_time); + time_arr = eina_strftime("%d/%m/%Y", info); + printf("Today's Date: %s\n", time_arr); + free(time_arr); + eina_shutdown(); return 0; diff --git a/src/lib/eina/eina_str.c b/src/lib/eina/eina_str.c index c3d9c4ca25..952f6ce94b 100644 --- a/src/lib/eina/eina_str.c +++ b/src/lib/eina/eina_str.c @@ -374,6 +374,39 @@ eina_strlcat(char *dst, const char *src, size_t siz) return(dlen + (s - src)); /* count does not include NUL */ } +EAPI char * +eina_strftime(const char *format, const struct tm *tm) +{ + const size_t flen = strlen(format); + size_t buflen = 16; // An arbitrary starting size + char *buf = NULL; + + do { + char *tmp; + size_t len; + + tmp = realloc(buf, buflen * sizeof(char)); + if (!tmp) goto on_error; + buf = tmp; + + len = strftime(buf, buflen, format, tm); + // Check if we have the expected result and return it. + if ((len > 0 && len < buflen) || (len == 0 && flen == 0)) + { + tmp = realloc(buf, ((len + 1) * sizeof(char))); + buf = tmp; + return buf; + } + + /* Possibly buf overflowed - try again with a bigger buffer */ + buflen <<= 1; // multiply buffer size by 2 + } while (buflen < 128 * flen); + + on_error: + free(buf); + return NULL; +} + EAPI Eina_Bool eina_str_has_prefix(const char *str, const char *prefix) { diff --git a/src/lib/eina/eina_str.h b/src/lib/eina/eina_str.h index 100cc81c48..0448269792 100644 --- a/src/lib/eina/eina_str.h +++ b/src/lib/eina/eina_str.h @@ -355,6 +355,32 @@ static inline size_t eina_strlen_bounded(const char *str, size_t maxlen) EINA_PU * @since 1.13 */ EAPI unsigned char *eina_memdup(unsigned char *mem, size_t size, Eina_Bool terminate); + +/** + * @brief Create and update the buffer based on strftime output. + * + * @param tm Pointer to a tm structure needed by strftime. + * @param format String containing format specifiers needed by strftime. + * @return Updated buffer based on strftime output + * + * This will create a buffer of exact required size based on strftime output + * once use is complete the buffer has to be freed using free. + * + * Example usage: + * @code + * time_t curr_time; + * struct tm *info; + * char *buf; + * curr_time = time(NULL); + * info = localtime(&curr_time); + * buf = eina_strftime("%I:%M%p", info); + * //after use + * free(buf); + * @endcode + * + * @since 1.16.0 + */ +EAPI char *eina_strftime(const char *format, const struct tm *tm); #include "eina_inline_str.x" /** diff --git a/src/tests/eina/eina_test_str.c b/src/tests/eina/eina_test_str.c index 8233dd8b37..97b3865a9d 100644 --- a/src/tests/eina/eina_test_str.c +++ b/src/tests/eina/eina_test_str.c @@ -347,6 +347,24 @@ START_TEST(str_memdup) } END_TEST +START_TEST(str_strftime) +{ + time_t curr_time; + struct tm *info; + char *buf; + eina_init(); + + curr_time = time(NULL); + info = localtime(&curr_time); + + buf = eina_strftime("%I:%M%p", info); + fail_if(buf == NULL); + free(buf); + + eina_shutdown(); +} +END_TEST + #ifdef HAVE_ICONV START_TEST(str_convert) { @@ -385,6 +403,7 @@ eina_test_str(TCase *tc) tcase_add_test(tc, str_lcat_lcpy); tcase_add_test(tc, str_join_len); tcase_add_test(tc, str_memdup); + tcase_add_test(tc, str_strftime); #ifdef HAVE_ICONV tcase_add_test(tc, str_convert); #endif