//
// Example:
// echo > /tmp/all.txt
-// for i in f_type f_status f_memory f_type_array f_string f_utf f_color f_console f_conversion f_file f_pipe f_print f_rip f_signal f_time f_thread ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
+// for i in f_type f_status f_memory f_type_array f_string f_utf f_color f_console f_conversion f_file f_pipe f_print f_rip f_signal f_thread f_time ; do grep -horP '\b_di_f_\w*\b' level_0/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_0/$i/c >> /tmp/all.txt ; done
// for i in fl_print ; do grep -horP '\b_di_fl_\w*\b' level_1/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_1/$i/c >> /tmp/all.txt ; done
// for i in fll_error fll_print fll_program ; do grep -horP '\b_di_fll_\w*\b' level_2/$i/c >> /tmp/all.txt ; grep -horP '\b_di_macro_\w*\b' level_2/$i/c >> /tmp/all.txt ; done
// sort /tmp/all.txt | uniq | sed -e 's|^_|#define &|g' > /tmp/sorted.txt
#define _di_f_thread_unlock_
#define _di_f_time_calendar_string_
#define _di_f_time_calendar_string_part_
+#define _di_f_time_clock_get_
+#define _di_f_time_clock_precision_
+#define _di_f_time_clock_set_
#define _di_f_time_d_
#define _di_f_time_epoch_get_
#define _di_f_time_local_get_
#define _di_f_thread_unlock_
#define _di_f_time_calendar_string_
#define _di_f_time_calendar_string_part_
+#define _di_f_time_clock_get_
+#define _di_f_time_clock_precision_
+#define _di_f_time_clock_set_
#define _di_f_time_d_
#define _di_f_time_epoch_get_
#define _di_f_time_local_get_
}
#endif // _di_f_time_calendar_string_part_
+#ifndef _di_f_time_clock_get_
+ f_status_t f_time_clock_get(const clockid_t code, f_time_spec_t * const time) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!time) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (clock_gettime(code, time)) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ENODEV) return F_status_set_error(F_device_not);
+ if (errno == ENOTSUP) return F_status_set_error(F_support_not);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == EOVERFLOW) return F_status_set_error(F_buffer_overflow);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_okay;
+ }
+#endif // _di_f_time_clock_get_
+
+#ifndef _di_f_time_clock_precision_
+ f_status_t f_time_clock_precision(const clockid_t code, f_time_spec_t * const precision) {
+ #ifndef _di_level_0_parameter_checking_
+ if (!precision) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ if (clock_getres(code, precision)) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ENODEV) return F_status_set_error(F_device_not);
+ if (errno == ENOTSUP) return F_status_set_error(F_support_not);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == EOVERFLOW) return F_status_set_error(F_buffer_overflow);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_okay;
+ }
+#endif // _di_f_time_clock_precision_
+
+#ifndef _di_f_time_clock_set_
+ f_status_t f_time_clock_set(const clockid_t code, const f_time_spec_t time) {
+
+ if (clock_settime(code, &time)) {
+ if (errno == EACCES) return F_status_set_error(F_access_denied);
+ if (errno == EFAULT) return F_status_set_error(F_buffer);
+ if (errno == ENODEV) return F_status_set_error(F_device_not);
+ if (errno == ENOTSUP) return F_status_set_error(F_support_not);
+ if (errno == EINVAL) return F_status_set_error(F_parameter);
+ if (errno == EOVERFLOW) return F_status_set_error(F_buffer_overflow);
+ if (errno == EPERM) return F_status_set_error(F_prohibited);
+
+ return F_status_set_error(F_failure);
+ }
+
+ return F_okay;
+ }
+#endif // _di_f_time_clock_set_
+
#ifndef _di_f_time_epoch_get_
f_status_t f_time_epoch_get(time_t * const time_value) {
#ifndef _di_level_0_parameter_checking_
#endif // _di_f_time_calendar_string_part_
/**
+ * Get the current seconds and nanoseconds from the system clock.
+ *
+ * @param code
+ * Designates how to get the time from the system clock.
+ * @param time
+ * The time retrieved.
+ *
+ * Must not be NULL.
+ *
+ * @return
+ * F_okay on success.
+ *
+ * F_access_denied (with error bit) on access denied.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_buffer_overflow (with error bit) if the time stamp does not fit in the time range.
+ * F_device_not (with error bit) if the system clock is no onger available (such as when a hot-pluggable clock disappears).
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if not permitted to perform this operation.
+ * F_support_not (with error bit) if the operation specified by the code is not supported by the clock.
+ *
+ * F_failure (with error bit) on any other error.
+ *
+ * @see clock_gettime()
+ */
+#ifndef _di_f_time_clock_get_
+ extern f_status_t f_time_clock_get(const clockid_t code, f_time_spec_t * const time);
+#endif // _di_f_time_clock_get_
+
+/**
+ * Get the precision from the system clock.
+ *
+ * @param code
+ * Designates how to get the time from the system clock.
+ * @param precision
+ * The clock precision (clock resolution).
+ *
+ * Must not be NULL.
+ *
+ * @return
+ * F_okay on success.
+ *
+ * F_access_denied (with error bit) on access denied.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_buffer_overflow (with error bit) if the time stamp does not fit in the time range.
+ * F_device_not (with error bit) if the system clock is no onger available (such as when a hot-pluggable clock disappears).
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if not permitted to perform this operation.
+ * F_support_not (with error bit) if the operation specified by the code is not supported by the clock.
+ *
+ * F_failure (with error bit) on any other error.
+ *
+ * @see clock_getres()
+ */
+#ifndef _di_f_time_clock_precision_
+ extern f_status_t f_time_clock_precision(const clockid_t code, f_time_spec_t * const precision);
+#endif // _di_f_time_clock_precision_
+
+/**
+ * Set the current seconds and nanoseconds from the system clock.
+ *
+ * @param code
+ * Designates how to set the time of the system clock.
+ * @param time
+ * The time to set.
+ *
+ * @return
+ * F_okay on success.
+ *
+ * F_access_denied (with error bit) on access denied.
+ * F_buffer (with error bit) if the buffer is invalid.
+ * F_buffer_overflow (with error bit) if the time stamp does not fit in the time range.
+ * F_device_not (with error bit) if the system clock is no onger available (such as when a hot-pluggable clock disappears).
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_prohibited (with error bit) if not permitted to perform this operation.
+ * F_support_not (with error bit) if the operation specified by the code is not supported by the clock.
+ *
+ * F_failure (with error bit) on any other error.
+ *
+ * @see clock_settime()
+ */
+#ifndef _di_f_time_clock_set_
+ extern f_status_t f_time_clock_set(const clockid_t code, const f_time_spec_t time);
+#endif // _di_f_time_clock_set_
+
+/**
* Get the current time in seconds since epoch.
*
* @param time
# Inject mocks.
flags -Wl,--wrap=asctime_r
+flags -Wl,--wrap=clock_getres
+flags -Wl,--wrap=clock_gettime
+flags -Wl,--wrap=clock_settime
flags -Wl,--wrap=ctime_r
flags -Wl,--wrap=f_string_append
flags -Wl,--wrap=gettimeofday
build_libraries-individual -lf_memory -lf_string -lf_time
build_sources_program test-time-calendar_string.c test-time-calendar_string_part.c test-time-epoch_get.c
+build_sources_program test-time-clock_get.c test-time-clock_precision.c test-time-clock_set.c
build_sources_program test-time-of_day_get.c test-time-of_day_set.c
build_sources_program test-time-local_get.c test-time-utc_get.c
build_sources_program test-time-sleep_spec.c test-time-spec_millisecond.c test-time-spec_nanosecond.c
return mock_type(time_t);
}
+int __wrap_clock_getres(clockid_t clockid, struct timespec *tp) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return -1;
+ }
+
+ if (tp) {
+ *tp = *mock_type(struct timespec *);
+ }
+
+ return 0;
+}
+
+int __wrap_clock_gettime(clockid_t clockid, struct timespec *tp) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return -1;
+ }
+
+ if (tp) {
+ *tp = *mock_type(struct timespec *);
+ }
+
+ return 0;
+}
+
+int __wrap_clock_settime(clockid_t clockid, const struct timespec *tp) {
+
+ const bool failure = mock_type(bool);
+
+ if (failure) {
+ errno = mock_type(int);
+
+ return -1;
+ }
+
+ return 0;
+}
+
#ifdef __cplusplus
} // extern "C"
#endif
extern f_status_t __wrap_f_string_append(const f_string_t source, const f_number_unsigned_t length, f_string_dynamic_t * const destination);
extern char *__wrap_asctime_r(const struct tm *tm, char *buf);
+extern int __wrap_clock_getres(clockid_t clockid, struct timespec *tp);
+extern int __wrap_clock_gettime(clockid_t clockid, struct timespec *tp);
+extern int __wrap_clock_settime(clockid_t clockid, const struct timespec *tp);
extern char *__wrap_ctime_r(const time_t *timep, char *buf);
extern int __wrap_gettimeofday(struct timeval *tv, struct timezone *tz);
extern struct tm *__wrap_gmtime_r(const time_t *timep, struct tm *result);
--- /dev/null
+#include "test-time.h"
+#include "test-time-clock_get.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_time_clock_get__fails(void **state) {
+
+ {
+ int errnos[] = {
+ EACCES,
+ EFAULT,
+ ENODEV,
+ ENOTSUP,
+ EINVAL,
+ EOVERFLOW,
+ EPERM,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_status_set_error(F_access_denied),
+ F_status_set_error(F_buffer),
+ F_status_set_error(F_device_not),
+ F_status_set_error(F_support_not),
+ F_status_set_error(F_parameter),
+ F_status_set_error(F_buffer_overflow),
+ F_status_set_error(F_prohibited),
+ F_status_set_error(F_failure),
+ };
+
+ for (int i = 0; i < 8; ++i) {
+
+ f_time_spec_t time = f_time_spec_t_initialize;
+
+ will_return(__wrap_clock_gettime, true);
+ will_return(__wrap_clock_gettime, errnos[i]);
+
+ const f_status_t status = f_time_clock_get(0, &time);
+
+ assert_int_equal(status, statuss[i]);
+ } // for
+ }
+}
+
+void test__f_time_clock_get__parameter_checking(void **state) {
+
+ {
+ const f_status_t status = f_time_clock_get(0, 0);
+
+ assert_int_equal(status, F_status_set_error(F_parameter));
+ }
+}
+
+void test__f_time_clock_get__works(void **state) {
+
+ const f_time_spec_t expect = { .tv_sec = 1, .tv_nsec = 2 };
+
+ {
+ f_time_spec_t time = f_time_spec_t_initialize;
+
+ will_return(__wrap_clock_gettime, false);
+ will_return(__wrap_clock_gettime, &expect);
+
+ const f_status_t status = f_time_clock_get(0, &time);
+
+ assert_int_equal(status, F_okay);
+ assert_int_equal(time.tv_sec, expect.tv_sec);
+ assert_int_equal(time.tv_nsec, expect.tv_nsec);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Time
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the time project.
+ */
+#ifndef _TEST__F_time_clock_get_h
+#define _TEST__F_time_clock_get_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_time_clock_get()
+ */
+extern void test__f_time_clock_get__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_time_clock_get()
+ */
+extern void test__f_time_clock_get__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_time_clock_get()
+ */
+extern void test__f_time_clock_get__works(void **state);
+
+#endif // _TEST__F_time_clock_get_h
--- /dev/null
+#include "test-time.h"
+#include "test-time-clock_precision.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_time_clock_precision__fails(void **state) {
+
+ {
+ int errnos[] = {
+ EACCES,
+ EFAULT,
+ ENODEV,
+ ENOTSUP,
+ EINVAL,
+ EOVERFLOW,
+ EPERM,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_status_set_error(F_access_denied),
+ F_status_set_error(F_buffer),
+ F_status_set_error(F_device_not),
+ F_status_set_error(F_support_not),
+ F_status_set_error(F_parameter),
+ F_status_set_error(F_buffer_overflow),
+ F_status_set_error(F_prohibited),
+ F_status_set_error(F_failure),
+ };
+
+ for (int i = 0; i < 8; ++i) {
+
+ f_time_spec_t time = f_time_spec_t_initialize;
+
+ will_return(__wrap_clock_getres, true);
+ will_return(__wrap_clock_getres, errnos[i]);
+
+ const f_status_t status = f_time_clock_precision(0, &time);
+
+ assert_int_equal(status, statuss[i]);
+ } // for
+ }
+}
+
+void test__f_time_clock_precision__parameter_checking(void **state) {
+
+ {
+ const f_status_t status = f_time_clock_precision(0, 0);
+
+ assert_int_equal(status, F_status_set_error(F_parameter));
+ }
+}
+
+void test__f_time_clock_precision__works(void **state) {
+
+ const f_time_spec_t expect = { .tv_sec = 1, .tv_nsec = 2 };
+
+ {
+ f_time_spec_t time = f_time_spec_t_initialize;
+
+ will_return(__wrap_clock_getres, false);
+ will_return(__wrap_clock_getres, &expect);
+
+ const f_status_t status = f_time_clock_precision(0, &time);
+
+ assert_int_equal(status, F_okay);
+ assert_int_equal(time.tv_sec, expect.tv_sec);
+ assert_int_equal(time.tv_nsec, expect.tv_nsec);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Time
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the time project.
+ */
+#ifndef _TEST__F_time_clock_precision_h
+#define _TEST__F_time_clock_precision_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_time_clock_precision()
+ */
+extern void test__f_time_clock_precision__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_time_clock_precision()
+ */
+extern void test__f_time_clock_precision__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_time_clock_precision()
+ */
+extern void test__f_time_clock_precision__works(void **state);
+
+#endif // _TEST__F_time_clock_precision_h
--- /dev/null
+#include "test-time.h"
+#include "test-time-clock_set.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_time_clock_set__fails(void **state) {
+
+ const f_time_spec_t time = f_time_spec_t_initialize;
+
+ {
+ int errnos[] = {
+ EACCES,
+ EFAULT,
+ ENODEV,
+ ENOTSUP,
+ EINVAL,
+ EOVERFLOW,
+ EPERM,
+ mock_errno_generic,
+ };
+
+ f_status_t statuss[] = {
+ F_status_set_error(F_access_denied),
+ F_status_set_error(F_buffer),
+ F_status_set_error(F_device_not),
+ F_status_set_error(F_support_not),
+ F_status_set_error(F_parameter),
+ F_status_set_error(F_buffer_overflow),
+ F_status_set_error(F_prohibited),
+ F_status_set_error(F_failure),
+ };
+
+ for (int i = 0; i < 8; ++i) {
+
+ will_return(__wrap_clock_settime, true);
+ will_return(__wrap_clock_settime, errnos[i]);
+
+ const f_status_t status = f_time_clock_set(0, time);
+
+ assert_int_equal(status, statuss[i]);
+ } // for
+ }
+}
+
+void test__f_time_clock_set__works(void **state) {
+
+ {
+ const f_time_spec_t time = f_time_spec_t_initialize;
+
+ will_return(__wrap_clock_settime, false);
+
+ const f_status_t status = f_time_clock_set(0, time);
+
+ assert_int_equal(status, F_okay);
+ }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: Time
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the time project.
+ */
+#ifndef _TEST__F_time_clock_set_h
+#define _TEST__F_time_clock_set_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_time_clock_set()
+ */
+extern void test__f_time_clock_set__fails(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_time_clock_set()
+ */
+extern void test__f_time_clock_set__works(void **state);
+
+#endif // _TEST__F_time_clock_set_h
const struct CMUnitTest tests[] = {
cmocka_unit_test(test__f_time_calendar_string__fails),
cmocka_unit_test(test__f_time_calendar_string_part__fails),
+ cmocka_unit_test(test__f_time_clock_get__fails),
+ cmocka_unit_test(test__f_time_clock_precision__fails),
+ cmocka_unit_test(test__f_time_clock_set__fails),
cmocka_unit_test(test__f_time_epoch_get__fails),
cmocka_unit_test(test__f_time_local_get__fails),
cmocka_unit_test(test__f_time_of_day_get__fails),
cmocka_unit_test(test__f_time_calendar_string__works),
cmocka_unit_test(test__f_time_calendar_string_part__works),
+ cmocka_unit_test(test__f_time_clock_get__works),
+ cmocka_unit_test(test__f_time_clock_precision__works),
+ cmocka_unit_test(test__f_time_clock_set__works),
cmocka_unit_test(test__f_time_epoch_get__works),
cmocka_unit_test(test__f_time_local_get__works),
cmocka_unit_test(test__f_time_of_day_get__works),
#ifndef _di_level_0_parameter_checking_
cmocka_unit_test(test__f_time_calendar_string__parameter_checking),
cmocka_unit_test(test__f_time_calendar_string_part__parameter_checking),
+ cmocka_unit_test(test__f_time_clock_get__parameter_checking),
+ cmocka_unit_test(test__f_time_clock_precision__parameter_checking),
+ // f_time_clock_set() doesn't use parameter checking.
cmocka_unit_test(test__f_time_epoch_get__parameter_checking),
cmocka_unit_test(test__f_time_local_get__parameter_checking),
cmocka_unit_test(test__f_time_of_day_get__parameter_checking),
// Test includes.
#include "test-time-calendar_string.h"
#include "test-time-calendar_string_part.h"
+#include "test-time-clock_get.h"
+#include "test-time-clock_precision.h"
+#include "test-time-clock_set.h"
#include "test-time-epoch_get.h"
#include "test-time-local_get.h"
#include "test-time-of_day_get.h"