aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Łyszczek <michal.lyszczek@bofc.pl>2018-01-24 17:46:56 +0100
committerMichał Łyszczek <michal.lyszczek@bofc.pl>2018-01-24 18:07:51 +0100
commit092a7002d872e8228dc7bad1689d67a54513d185 (patch)
tree61d23e82fe1d6cc19c68939f5bce236b68545fe7
parent67ec9f6de34b995a0bcd57963a02d2d6ed3eaac5 (diff)
downloadembedlog-092a7002d872e8228dc7bad1689d67a54513d185.tar.gz
embedlog-092a7002d872e8228dc7bad1689d67a54513d185.tar.bz2
embedlog-092a7002d872e8228dc7bad1689d67a54513d185.zip
fix: distcheck errors when calling distclean
I know, I know these links are ugly as my ex, but blame autoconf, for not letting to use common source files with multiple targets.
-rw-r--r--embedlog-sources.mk13
-rw-r--r--examples/Makefile.am11
l---------examples/el-file.c1
l---------examples/el-options.c1
l---------examples/el-perror.c1
l---------examples/el-pmemory.c1
l---------examples/el-print.c1
l---------examples/el-puts.c1
l---------examples/snprintf.c1
-rw-r--r--src/Makefile.am23
-rw-r--r--tst/Makefile.am42
l---------[-rw-r--r--]tst/el-file.c1156
l---------[-rw-r--r--]tst/el-options.c322
l---------[-rw-r--r--]tst/el-perror.c174
l---------[-rw-r--r--]tst/el-pmemory.c310
l---------[-rw-r--r--]tst/el-print.c819
l---------tst/el-puts.c1
l---------tst/snprintf.c1
-rw-r--r--tst/test-el-file.c1155
-rw-r--r--tst/test-el-options.c321
-rw-r--r--tst/test-el-perror.c173
-rw-r--r--tst/test-el-pmemory.c309
-rw-r--r--tst/test-el-print.c818
23 files changed, 2830 insertions, 2825 deletions
diff --git a/embedlog-sources.mk b/embedlog-sources.mk
new file mode 100644
index 0000000..526a362
--- /dev/null
+++ b/embedlog-sources.mk
@@ -0,0 +1,13 @@
+embedlog_sources = el-options.c \
+ el-perror.c \
+ el-pmemory.c \
+ el-print.c \
+ el-puts.c
+
+if ENABLE_OUT_FILE
+embedlog_sources += el-file.c
+endif
+
+if CUSTOM_SNPRINTF
+embedlog_sources += snprintf.c
+endif
diff --git a/examples/Makefile.am b/examples/Makefile.am
index ef61e57..10032f0 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,7 +1,8 @@
+include $(top_srcdir)/embedlog-sources.mk
bin_PROGRAMS = print_to_file print_options print_simple print_memory
-LDADD = -lembedlog
+CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/src
-print_to_file_SOURCES = print-to-file.c
-print_options_SOURCES = print-options.c
-print_simple_SOURCES = print-simple.c
-print_memory_SOURCES = print-memory.c
+print_to_file_SOURCES = print-to-file.c $(embedlog_sources)
+print_options_SOURCES = print-options.c $(embedlog_sources)
+print_simple_SOURCES = print-simple.c $(embedlog_sources)
+print_memory_SOURCES = print-memory.c $(embedlog_sources)
diff --git a/examples/el-file.c b/examples/el-file.c
new file mode 120000
index 0000000..12ef212
--- /dev/null
+++ b/examples/el-file.c
@@ -0,0 +1 @@
+../src/el-file.c \ No newline at end of file
diff --git a/examples/el-options.c b/examples/el-options.c
new file mode 120000
index 0000000..7265099
--- /dev/null
+++ b/examples/el-options.c
@@ -0,0 +1 @@
+../src/el-options.c \ No newline at end of file
diff --git a/examples/el-perror.c b/examples/el-perror.c
new file mode 120000
index 0000000..cc73051
--- /dev/null
+++ b/examples/el-perror.c
@@ -0,0 +1 @@
+../src/el-perror.c \ No newline at end of file
diff --git a/examples/el-pmemory.c b/examples/el-pmemory.c
new file mode 120000
index 0000000..5dcc35f
--- /dev/null
+++ b/examples/el-pmemory.c
@@ -0,0 +1 @@
+../src/el-pmemory.c \ No newline at end of file
diff --git a/examples/el-print.c b/examples/el-print.c
new file mode 120000
index 0000000..1b5a73a
--- /dev/null
+++ b/examples/el-print.c
@@ -0,0 +1 @@
+../src/el-print.c \ No newline at end of file
diff --git a/examples/el-puts.c b/examples/el-puts.c
new file mode 120000
index 0000000..774e523
--- /dev/null
+++ b/examples/el-puts.c
@@ -0,0 +1 @@
+../src/el-puts.c \ No newline at end of file
diff --git a/examples/snprintf.c b/examples/snprintf.c
new file mode 120000
index 0000000..52193de
--- /dev/null
+++ b/examples/snprintf.c
@@ -0,0 +1 @@
+../src/snprintf.c \ No newline at end of file
diff --git a/src/Makefile.am b/src/Makefile.am
index 0f93367..a3d3e3c 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,22 +1,11 @@
+include $(top_srcdir)/embedlog-sources.mk
+
lib_LTLIBRARIES = libembedlog.la
-libembedlog_la_SOURCES = el-print.c \
- el-puts.c \
- el-perror.c \
- el-pmemory.c \
- el-options.c
+libembedlog_la_SOURCES = $(embedlog_sources)
libembedlog_la_SOURCES += config-priv.h \
- el-file.h \
- el-options.h \
- valid.h
-
-if ENABLE_OUT_FILE
-libembedlog_la_SOURCES += el-file.c
-endif
-
-if CUSTOM_SNPRINTF
-libembedlog_la_SOURCES += snprintf.c
-endif
-
+ el-file.h \
+ el-options.h \
+ valid.h
libembedlog_la_LDFLAGS = -version-info 1:1:1
libembedlog_la_CFLAGS = -I$(top_srcdir)/include
diff --git a/tst/Makefile.am b/tst/Makefile.am
index 3137fe0..abb9d97 100644
--- a/tst/Makefile.am
+++ b/tst/Makefile.am
@@ -1,37 +1,25 @@
include Makefile.am.coverage
-
+include $(top_srcdir)/embedlog-sources.mk
check_PROGRAMS = test
-test_SOURCES = main.c \
- el-options.c \
- el-print.c \
- el-file.c \
- el-perror.c \
- el-pmemory.c \
- mtest.h \
- test-group-list.h
-
-test_SOURCES += ../src/el-print.c \
- ../src/el-puts.c \
- ../src/el-perror.c \
- ../src/el-pmemory.c \
- ../src/el-options.c
-
-if ENABLE_OUT_FILE
-test_SOURCES += ../src/el-file.c
-endif
-if CUSTOM_SNPRINTF
-test_SOURCES += ../src/snprintf.c
-endif
+test_SOURCES = $(embedlog_sources)
+test_SOURCES += main.c \
+ test-el-options.c \
+ test-el-print.c \
+ test-el-file.c \
+ test-el-perror.c \
+ test-el-pmemory.c \
+ mtest.h \
+ test-group-list.h
test_CFLAGS = -I$(top_srcdir)/include \
- -I$(top_srcdir)/src \
- -I/usr/local/include \
- -O0 -g3 -ggdb \
- $(COVERAGE_CFLAGS)
+ -I$(top_srcdir)/src \
+ -I/usr/local/include \
+ -O0 -g3 -ggdb \
+ $(COVERAGE_CFLAGS)
test_LDFLAGS = -L/usr/local/lib \
- $(COVERAGE_LDFLAGS)
+ $(COVERAGE_LDFLAGS)
test_LDADD = -lrb
TESTS = $(check_PROGRAMS)
diff --git a/tst/el-file.c b/tst/el-file.c
index a74b113..12ef212 100644..120000
--- a/tst/el-file.c
+++ b/tst/el-file.c
@@ -1,1155 +1 @@
-/* ==========================================================================
- Licensed under BSD 2clause license See LICENSE file for more information
- Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
- ========================================================================== */
-
-
-/* ==========================================================================
- _ __ __ ____ _ __
- (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
- / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
- / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
- /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
-
- ========================================================================== */
-
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <limits.h>
-#include <errno.h>
-
-#include "mtest.h"
-#include "embedlog.h"
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- _ __ __
- _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
- | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
- | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
- |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
-
- ========================================================================== */
-
-
-#define WORKDIR "/tmp/embedlog-tests"
-#define s9 "123456789"
-#define s8 "qwertyui"
-#define s5 "qwert"
-#define s3 "asd"
-mt_defs_ext();
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- ____ __ _
- / __/__ __ ____ _____ / /_ (_)____ ____ _____
- / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
- / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
- /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
-
- ========================================================================== */
-
-
-static int file_check
-(
- const char *f,
- const char *s
-)
-{
- char fc[128];
- int fd;
- ssize_t r;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- fd = open(f, O_RDONLY);
- r = read(fd, fc, sizeof(fc));
- close(fd);
-
- fc[r] = '\0';
- if(strcmp(s, fc) != 0)
- {
- return -1;
- }
-
- return 0;
-}
-
-
-/* ==========================================================================
-
- ========================================================================== */
-
-
-static void test_prepare(void)
-{
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 0);
- el_option(EL_FNAME, WORKDIR"/log");
-
-}
-
-
-/* ==========================================================================
-
- ========================================================================== */
-
-
-static void test_cleanup(void)
-{
- int i;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- /*
- * remove any file that might have been created during tests. We ignore
- * unlink return code, as we expected that some files won't exist, as in
- * are not needed by tests and thus are not created
- */
-
- unlink(WORKDIR"/log");
- unlink(WORKDIR"/log-another");
-
- for (i = 0; i != 5; ++i)
- {
- char path1[PATH_MAX] = WORKDIR"/log.";
- char path2[PATH_MAX] = WORKDIR"/log-another.";
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- path1[strlen(path1)] = '0' + i;
- path2[strlen(path2)] = '0' + i;
- unlink(path1);
- unlink(path2);
- }
-
- el_cleanup();
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ _____
- / __// _ \ / ___// __// ___/
- / /_ / __/(__ )/ /_ (__ )
- \__/ \___//____/ \__//____/
-
- ========================================================================== */
-
-
-static void file_single_message(void)
-{
- el_puts(s9);
- mt_fok(file_check(WORKDIR"/log", s9));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_multi_message(void)
-{
- el_puts(s9);
- el_puts(s8);
- el_puts(s5);
- mt_fok(file_check(WORKDIR"/log", s9 s8 s5));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_reopen(void)
-{
- el_puts(s9);
- el_cleanup();
-
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 0);
- el_option(EL_FNAME, WORKDIR"/log");
-
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log", s9 s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_reopen_different_file(void)
-{
- el_puts(s9);
- el_cleanup();
-
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 0);
- el_option(EL_FNAME, WORKDIR"/log-another");
-
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log", s9));
- mt_fok(file_check(WORKDIR"/log-another", s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_unexpected_third_party_delete(void)
-{
- el_puts(s9);
- unlink(WORKDIR"/log");
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log", s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_filename_too_long(void)
-{
- char path[NAME_MAX + 1 + 1];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- memset(path, 'a', sizeof(path));
- path[sizeof(path) - 1] = '\0';
- mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_path_too_long(void)
-{
- char path[PATH_MAX + 2];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- memset(path, 'a', sizeof(path));
- path[0] = '/';
- path[sizeof(path) - 5] = '/';
- path[sizeof(path) - 4] = 'f';
- path[sizeof(path) - 4] = 'i';
- path[sizeof(path) - 3] = 'l';
- path[sizeof(path) - 2] = 'e';
- path[sizeof(path) - 1] = '\0';
- mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_print_without_init(void)
-{
- mt_ferr(el_puts("whatev..."), ENODEV);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_print_after_cleanup(void)
-{
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 0);
- el_option(EL_FNAME, WORKDIR"/log");
- el_cleanup();
- mt_ferr(el_puts("whatev"), ENODEV);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_print_without_setting_file(void)
-{
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 0);
- mt_ferr(el_puts("no file set"), EBADF);
- el_cleanup();
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_no_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s9);
- mt_fok(file_check(WORKDIR"/log.0", s9));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_exact_print(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s8);
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s8 s8));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_overflow_but_no_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s9 s5 s5);
- mt_fok(file_check(WORKDIR"/log.0", s9 s5 "qw"));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_overflow(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s9);
- el_puts(s9);
- el_puts(s3);
- mt_fok(file_check(WORKDIR"/log.0", s9 s3));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_overflow_exact(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s8);
- el_puts(s8);
- el_puts(s5);
- mt_fok(file_check(WORKDIR"/log.0", s5));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_reopen(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s5);
-
- el_cleanup();
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 1);
- el_option(EL_FNAME, WORKDIR"/log");
-
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s5 s8));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_unexpected_third_party_remove(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s5);
- el_puts(s8);
- unlink(WORKDIR"/log.0");
- el_puts(s3);
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s3 s8));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_change_size_up(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s9);
- el_puts(s5);
- el_option(EL_FROTATE_SIZE, 32);
- el_puts(s9);
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s9 s5 s9 s8));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_1_change_size_down(void)
-{
- el_option(EL_FROTATE_NUMBER, 1);
- el_puts(s9);
- el_option(EL_FROTATE_SIZE, 8);
- el_puts(s5);
- mt_fok(file_check(WORKDIR"/log.0", s5));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_no_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s9);
- mt_fok(file_check(WORKDIR"/log.0", s9));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_exact_print(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s8);
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s8 s8));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_overflow_but_no_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s9 s5 s5);
- mt_fok(file_check(WORKDIR"/log.0", s9 s5 "qw"));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_overflow(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s9);
- el_puts(s9);
- el_puts(s3);
- mt_fok(file_check(WORKDIR"/log.0", s9));
- mt_fok(file_check(WORKDIR"/log.1", s9 s3));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_overflow_exact(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s8);
- el_puts(s8);
- el_puts(s5);
- mt_fok(file_check(WORKDIR"/log.0", s8 s8));
- mt_fok(file_check(WORKDIR"/log.1", s5));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_reopen(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s9);
- el_puts(s8);
-
- el_cleanup();
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 2);
- el_option(EL_FNAME, WORKDIR"/log");
-
- el_puts(s5);
- mt_fok(file_check(WORKDIR"/log.0", s9));
- mt_fok(file_check(WORKDIR"/log.1", s8 s5));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_unexpected_third_party_remove(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s5);
- el_puts(s8);
- unlink(WORKDIR"/log.0");
- el_puts(s3);
- el_puts(s8);
- el_puts(s9);
- mt_fok(file_check(WORKDIR"/log.0", s3 s8));
- mt_fok(file_check(WORKDIR"/log.1", s9));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_change_size_up(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s9);
- el_puts(s5);
- el_puts(s9);
- el_option(EL_FROTATE_SIZE, 32);
- el_puts(s9);
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s9 s5));
- mt_fok(file_check(WORKDIR"/log.1", s9 s9 s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_change_size_down(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s9);
- el_puts(s9);
- el_option(EL_FROTATE_SIZE, 8);
- el_puts(s5);
- mt_fok(file_check(WORKDIR"/log.0", s9));
- mt_fok(file_check(WORKDIR"/log.1", s5));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_2_many_rotates(void)
-{
- el_option(EL_FROTATE_NUMBER, 2);
- el_puts(s9);
- el_puts(s8);
- el_puts(s5);
- el_puts(s5);
- el_puts(s3);
- el_puts(s9);
- mt_fok(file_check(WORKDIR"/log.0", s5 s3));
- mt_fok(file_check(WORKDIR"/log.1", s9));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_no_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- el_puts(s9);
- mt_fok(file_check(WORKDIR"/log.0", s9));
- mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_exact_print_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- el_puts(s8);
- el_puts(s8);
- el_puts(s8);
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s8 s8));
- mt_fok(file_check(WORKDIR"/log.1", s8 s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_overflow_but_no_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- el_puts(s8);
- el_puts(s8);
- el_puts(s9 s5 s5);
- mt_fok(file_check(WORKDIR"/log.0", s8 s8));
- mt_fok(file_check(WORKDIR"/log.1", s9 s5 "qw"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_overflow(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- el_puts(s9);
- el_puts(s9);
- el_puts(s3);
- el_puts(s3);
- el_puts(s8);
- el_puts(s5);
- el_puts(s9);
- mt_fok(file_check(WORKDIR"/log.0", s9));
- mt_fok(file_check(WORKDIR"/log.1", s9 s3 s3));
- mt_fok(file_check(WORKDIR"/log.2", s8 s5));
- mt_fok(file_check(WORKDIR"/log.3", s9));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_overflow_exact(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- el_puts(s8);
- el_puts(s8);
- el_puts(s8);
- el_puts(s8);
- el_puts(s5);
- mt_fok(file_check(WORKDIR"/log.0", s8 s8));
- mt_fok(file_check(WORKDIR"/log.1", s8 s8));
- mt_fok(file_check(WORKDIR"/log.2", s5));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_reopen(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
-
- el_puts(s9);
- el_puts(s9);
- el_puts(s3);
- el_puts(s3);
- el_puts(s8);
- el_puts(s5);
-
- el_cleanup();
- el_init();
- el_option(EL_OUT, EL_OUT_FILE);
- el_option(EL_FROTATE_SIZE, 16);
- el_option(EL_FROTATE_NUMBER, 5);
- el_option(EL_FNAME, WORKDIR"/log");
-
- el_puts(s9);
- el_puts(s8);
- mt_fok(file_check(WORKDIR"/log.0", s9));
- mt_fok(file_check(WORKDIR"/log.1", s9 s3 s3));
- mt_fok(file_check(WORKDIR"/log.2", s8 s5));
- mt_fok(file_check(WORKDIR"/log.3", s9));
- mt_fok(file_check(WORKDIR"/log.4", s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_hole_in_log_rotate(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- el_option(EL_FROTATE_SIZE, 3);
- el_puts("qaz");
- el_puts("wsx");
- el_puts("edc");
- el_puts("rfv");
- el_puts("tgb");
-
- mt_fok(file_check(WORKDIR"/log.0", "qaz"));
- mt_fok(file_check(WORKDIR"/log.1", "wsx"));
- mt_fok(file_check(WORKDIR"/log.2", "edc"));
- mt_fok(file_check(WORKDIR"/log.3", "rfv"));
- mt_fok(file_check(WORKDIR"/log.4", "tgb"));
-
- unlink(WORKDIR"/log.1");
- unlink(WORKDIR"/log.4");
-
- el_puts("123");
-
- mt_fok(file_check(WORKDIR"/log.0", "qaz"));
- mt_fok(file_check(WORKDIR"/log.1", "edc"));
- mt_fok(file_check(WORKDIR"/log.2", "rfv"));
- mt_fok(file_check(WORKDIR"/log.4", "123"));
-
- el_puts("456");
-
- mt_fok(file_check(WORKDIR"/log.0", "edc"));
- mt_fok(file_check(WORKDIR"/log.1", "rfv"));
- mt_fok(file_check(WORKDIR"/log.3", "123"));
- mt_fok(file_check(WORKDIR"/log.4", "456"));
-
- el_puts("789");
-
- mt_fok(file_check(WORKDIR"/log.0", "rfv"));
- mt_fok(file_check(WORKDIR"/log.2", "123"));
- mt_fok(file_check(WORKDIR"/log.3", "456"));
- mt_fok(file_check(WORKDIR"/log.4", "789"));
-
- el_puts("qwe");
-
- mt_fok(file_check(WORKDIR"/log.0", "rfv"));
- mt_fok(file_check(WORKDIR"/log.1", "123"));
- mt_fok(file_check(WORKDIR"/log.2", "456"));
- mt_fok(file_check(WORKDIR"/log.3", "789"));
- mt_fok(file_check(WORKDIR"/log.4", "qwe"));
-
- el_puts("asd");
-
- mt_fok(file_check(WORKDIR"/log.0", "123"));
- mt_fok(file_check(WORKDIR"/log.1", "456"));
- mt_fok(file_check(WORKDIR"/log.2", "789"));
- mt_fok(file_check(WORKDIR"/log.3", "qwe"));
- mt_fok(file_check(WORKDIR"/log.4", "asd"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_5_rename_file_halfway(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- el_option(EL_FROTATE_SIZE, 3);
- el_puts("qaz");
- el_puts("wsx");
- el_puts("edc");
- el_puts("rfv");
- el_puts("tgb");
-
- el_option(EL_FNAME, WORKDIR"/log-another");
-
- el_puts("123");
- el_puts("456");
- el_puts("789");
- el_puts("qwe");
- el_puts("asd");
-
- mt_fok(file_check(WORKDIR"/log.0", "qaz"));
- mt_fok(file_check(WORKDIR"/log.1", "wsx"));
- mt_fok(file_check(WORKDIR"/log.2", "edc"));
- mt_fok(file_check(WORKDIR"/log.3", "rfv"));
- mt_fok(file_check(WORKDIR"/log.4", "tgb"));
-
- mt_fok(file_check(WORKDIR"/log-another.0", "123"));
- mt_fok(file_check(WORKDIR"/log-another.1", "456"));
- mt_fok(file_check(WORKDIR"/log-another.2", "789"));
- mt_fok(file_check(WORKDIR"/log-another.3", "qwe"));
- mt_fok(file_check(WORKDIR"/log-another.4", "asd"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_no_dir_for_logs(void)
-{
- mt_ferr(el_option(EL_FNAME, "/tmp/i-dont/exist"), ENOENT);
- mt_ferr(el_puts("whatever"), EBADF);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_dir_removed_after_open_then_created_back_again(void)
-{
- mt_fok(el_puts(s8));
- unlink(WORKDIR"/log");
- rmdir(WORKDIR);
- mt_ferr(el_puts(s3), EBADF);
- mkdir(WORKDIR, 0755);
- mt_fok(el_puts(s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_dir_no_access(void)
-{
- mkdir("/tmp/embedlog-no-write", 0555);
- if (getuid() == 0)
- {
- /*
- * root just doesn't give a fuck about no-write-permissions
- */
-
- mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
- mt_fok(el_puts(s3));
- mt_fok(file_check("/tmp/embedlog-no-write/log", s3));
- }
- else
- {
- mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
- mt_ferr(el_puts(s3), EBADF);
- }
- unlink("/tmp/embedlog-no-write/log");
- rmdir("/tmp/embedlog-no-write");
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_no_access_to_file(void)
-{
- int fd;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- mkdir("/tmp/embedlog-no-write", 0755);
- fd = open("/tmp/embedlog-no-write/log", O_CREAT, 0444);
- close(fd);
-
- if (getuid() == 0)
- {
- mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
- mt_fok(el_puts(s5));
- mt_fok(file_check("/tmp/embedlog-no-write/log", s5));
- }
- else
- {
- mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
- mt_ferr(el_puts("whatever"), EBADF);
- }
- unlink("/tmp/embedlog-no-write/log");
- rmdir("/tmp/embedlog-no-write");
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_no_dir_for_logs(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- mt_ferr(el_option(EL_FNAME, "/tmp/i-dont/exist"), ENOENT);
- mt_ferr(el_puts("whatever"), EBADF);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_dir_removed_after_open_then_created_back_again(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- mt_fok(el_puts(s8));
- mt_fok(el_puts(s8));
- mt_fok(el_puts(s8));
- mt_fok(el_puts(s8));
- mt_fok(el_puts(s8));
- unlink(WORKDIR"/log");
- unlink(WORKDIR"/log.0");
- unlink(WORKDIR"/log.1");
- unlink(WORKDIR"/log.2");
- rmdir(WORKDIR);
- mt_ferr(el_puts(s3), EBADF);
- mkdir(WORKDIR, 0755);
- mt_fok(el_puts(s8));
- mt_fok(el_puts(s5));
-
- mt_fok(file_check(WORKDIR"/log.2", s8 s5));
-
- mt_fok(el_puts(s8));
- mt_fok(el_puts(s3));
- mt_fok(el_puts(s5));
-
- mt_fok(file_check(WORKDIR"/log.2", s8 s5));
- mt_fok(file_check(WORKDIR"/log.3", s8 s3 s5));
-
- mt_fok(el_puts(s9));
- mt_fok(el_puts(s5));
-
- mt_fok(file_check(WORKDIR"/log.2", s8 s5));
- mt_fok(file_check(WORKDIR"/log.3", s8 s3 s5));
- mt_fok(file_check(WORKDIR"/log.4", s9 s5));
-
- mt_fok(el_puts(s3));
- mt_fok(el_puts(s8));
-
- mt_fok(file_check(WORKDIR"/log.1", s8 s5));
- mt_fok(file_check(WORKDIR"/log.2", s8 s3 s5));
- mt_fok(file_check(WORKDIR"/log.3", s9 s5));
- mt_fok(file_check(WORKDIR"/log.4", s3 s8));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_dir_no_access(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- mkdir("/tmp/embedlog-no-write", 0555);
-
- if (getuid() == 0)
- {
- mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
- mt_fok(el_puts(s3));
- mt_fok(file_check("/tmp/embedlog-no-write/log.0", s3));
- }
- else
- {
- mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
- mt_ferr(el_puts(s3), EBADF);
- }
-
- unlink("/tmp/embedlog-no-write/log.0");
- rmdir("/tmp/embedlog-no-write");
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_no_access_to_file(void)
-{
- int fd;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_option(EL_FROTATE_NUMBER, 5);
- mkdir("/tmp/embedlog-no-write", 0755);
- fd = open("/tmp/embedlog-no-write/log.0", O_CREAT, 0444);
- close(fd);
-
- if (getuid() == 0)
- {
- mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
- mt_fok(el_puts(s8));
- mt_fok(file_check("/tmp/embedlog-no-write/log.0", s8));
- }
- else
- {
- mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
- mt_ferr(el_puts("whatever"), EBADF);
- }
-
- unlink("/tmp/embedlog-no-write/log.0");
- rmdir("/tmp/embedlog-no-write");
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_filename_too_long(void)
-{
- char path[NAME_MAX];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- memset(path, 'a', sizeof(path));
- path[sizeof(path) - 1] = '\0';
- el_option(EL_FROTATE_NUMBER, 5);
- mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_path_too_long(void)
-{
- char path[PATH_MAX + 2];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- memset(path, 'a', sizeof(path));
- path[0] = '/';
- path[sizeof(path) - 5] = '/';
- path[sizeof(path) - 4] = 'f';
- path[sizeof(path) - 4] = 'i';
- path[sizeof(path) - 3] = 'l';
- path[sizeof(path) - 2] = 'e';
- path[sizeof(path) - 1] = '\0';
- el_option(EL_FROTATE_NUMBER, 5);
- mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void file_rotate_fail(void)
-{
- el_option(EL_FROTATE_NUMBER, 5);
- mt_fok(el_puts(s8));
- mt_fok(el_puts(s8));
- unlink(WORKDIR"/log");
- unlink(WORKDIR"/log.0");
- rmdir(WORKDIR);
- mt_ferr(el_puts(s3), ENOENT);
- mkdir(WORKDIR, 0755);
- mt_fok(el_puts(s8));
-
- mt_fok(file_check(WORKDIR"/log.1", s8));
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
- / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
- / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
- \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
- /____/ /_/
- ========================================================================== */
-
-
-void el_file_test_group(void)
-{
- mkdir(WORKDIR, 0755);
-
- mt_run(file_print_without_init);
- mt_run(file_print_after_cleanup);
- mt_run(file_print_without_setting_file);
-
- mt_prepare_test = &test_prepare;
- mt_cleanup_test = &test_cleanup;
-
- mt_run(file_single_message);
- mt_run(file_multi_message);
- mt_run(file_reopen);
- mt_run(file_reopen_different_file);
- mt_run(file_unexpected_third_party_delete);
- mt_run(file_filename_too_long);
- mt_run(file_path_too_long);
- mt_run(file_rotate_1_no_rotate);
- mt_run(file_rotate_1_exact_print);
- mt_run(file_rotate_1_overflow_but_no_rotate);
- mt_run(file_rotate_1_overflow);
- mt_run(file_rotate_1_overflow_exact);
- mt_run(file_rotate_1_reopen);
- mt_run(file_rotate_1_unexpected_third_party_remove);
- mt_run(file_rotate_1_change_size_up);
- mt_run(file_rotate_1_change_size_down);
- mt_run(file_rotate_2_no_rotate);
- mt_run(file_rotate_2_exact_print);
- mt_run(file_rotate_2_overflow_but_no_rotate);
- mt_run(file_rotate_2_overflow);
- mt_run(file_rotate_2_overflow_exact);
- mt_run(file_rotate_2_reopen);
- mt_run(file_rotate_2_unexpected_third_party_remove);
- mt_run(file_rotate_2_change_size_up);
- mt_run(file_rotate_2_change_size_down);
- mt_run(file_rotate_2_many_rotates);
- mt_run(file_rotate_5_no_rotate);
- mt_run(file_rotate_5_exact_print_rotate);
- mt_run(file_rotate_5_overflow_but_no_rotate);
- mt_run(file_rotate_5_overflow);
- mt_run(file_rotate_5_overflow_exact);
- mt_run(file_rotate_5_reopen);
- mt_run(file_rotate_5_hole_in_log_rotate);
- mt_run(file_rotate_5_rename_file_halfway);
- mt_run(file_no_dir_for_logs);
- mt_run(file_dir_removed_after_open_then_created_back_again);
- mt_run(file_dir_no_access);
- mt_run(file_no_access_to_file);
- mt_run(file_rotate_no_dir_for_logs);
- mt_run(file_rotate_dir_removed_after_open_then_created_back_again);
- mt_run(file_rotate_dir_no_access);
- mt_run(file_rotate_no_access_to_file);
- mt_run(file_rotate_filename_too_long);
- mt_run(file_rotate_path_too_long);
- mt_run(file_rotate_fail);
-
- rmdir(WORKDIR);
-}
+../src/el-file.c \ No newline at end of file
diff --git a/tst/el-options.c b/tst/el-options.c
index 1e6fa85..7265099 100644..120000
--- a/tst/el-options.c
+++ b/tst/el-options.c
@@ -1,321 +1 @@
-/* ==========================================================================
- Licensed under BSD 2clause license See LICENSE file for more information
- Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
- ========================================================================== */
-
-/* ==========================================================================
- _ __ __ ____ _ __
- (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
- / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
- / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
- /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
-
- ========================================================================== */
-
-
-#include <string.h>
-#include <errno.h>
-
-#include "embedlog.h"
-#include "el-options.h"
-#include "mtest.h"
-#include "test-group-list.h"
-#include "config.h"
-
-
-/* ==========================================================================
- __ __ __
- ____ _ / /____ / /_ ____ _ / /
- / __ `// // __ \ / __ \ / __ `// /
- / /_/ // // /_/ // /_/ // /_/ // /
- \__, //_/ \____//_.___/ \__,_//_/
- /____/
- _ __ __
- _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
- | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
- | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
- |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
-
- ========================================================================== */
-
-
-mt_defs_ext(); /* external variables for mtest */
-extern struct el_options g_options; /* global embedlog options */
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- _ __ __
- _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
- | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
- | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
- |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
-
- ========================================================================== */
-
-
-static void test_prepare(void)
-{
- el_init();
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void test_cleanup(void)
-{
- el_cleanup();
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ _____
- / __// _ \ / ___// __// ___/
- / /_ / __/(__ )/ /_ (__ )
- \__/ \___//____/ \__//____/
-
- ========================================================================== */
-
-
-static void options_init(void)
-{
- struct el_options default_options; /* expected default options */
- struct el_options options; /* custom options to init */
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- memset(&default_options, 0, sizeof(default_options));
- default_options.outputs = 0;
- default_options.level = EL_INFO;
- default_options.colors = 0;
- default_options.timestamp = EL_TS_OFF;
- default_options.timestamp_timer = EL_TS_TM_CLOCK;
- default_options.print_log_level = 1;
- default_options.custom_puts = NULL;
-
- default_options.finfo = 0;
- default_options.frotate_number = 0;
- default_options.fcurrent_rotate = 0;
- default_options.frotate_size = 0;
- default_options.fpos = 0;
- default_options.file = NULL;
- default_options.fname = NULL;
-
- mt_fail(el_oinit(&options) == 0);
- mt_fail(memcmp(&options, &default_options, sizeof(options)) == 0);
- mt_fail(el_ocleanup(&options) == 0);
-
- mt_fail(el_init() == 0);
- mt_fail(memcmp(&g_options, &default_options, sizeof(default_options)) == 0);
- mt_fail(el_cleanup() == 0);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_init_einval(void)
-{
- errno = 0;
- mt_fail(el_oinit(NULL) == -1);
- mt_fail(errno == EINVAL);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_level_set(void)
-{
- int i;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- for (i = 0; i != 32; ++i)
- {
- mt_fail(el_option(EL_LEVEL, i) == 0);
- mt_fail(g_options.level == i);
- }
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_output(void)
-{
- int current_outputs;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- current_outputs = 0;
- mt_fok(el_option(EL_OUT, EL_OUT_STDERR));
- mt_fail(g_options.outputs == EL_OUT_STDERR);
-
- mt_fok(el_option(EL_OUT, (EL_OUT_STDERR | EL_OUT_FILE)));
- mt_fail(g_options.outputs == (EL_OUT_STDERR | EL_OUT_FILE));
-
- mt_ferr(el_option(EL_OUT, EL_OUT_ALL + 7), EINVAL);
- mt_fail(g_options.outputs == (EL_OUT_STDERR | EL_OUT_FILE));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_log_allowed(void)
-{
- g_options.level = EL_ERROR;
- g_options.outputs = EL_OUT_STDERR;
-
- mt_fail(el_log_allowed(&g_options, EL_FATAL) == 1);
- mt_fail(el_log_allowed(&g_options, EL_ALERT) == 1);
- mt_fail(el_log_allowed(&g_options, EL_CRIT) == 1);
- mt_fail(el_log_allowed(&g_options, EL_ERROR) == 1);
- mt_fail(el_log_allowed(&g_options, EL_WARN) == 0);
- mt_fail(el_log_allowed(&g_options, EL_NOTICE) == 0);
- mt_fail(el_log_allowed(&g_options, EL_INFO) == 0);
- mt_fail(el_log_allowed(&g_options, EL_DBG) == 0);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_opt_print_level(void)
-{
- mt_fail(el_option(EL_PRINT_LEVEL, 0) == 0);
- mt_fail(g_options.print_log_level == 0);
- mt_fail(el_option(EL_PRINT_LEVEL, 1) == 0);
- mt_fail(g_options.print_log_level == 1);
-
- errno = 0;
- mt_fail(el_option(EL_PRINT_LEVEL, 2) == -1);
- mt_fail(errno == EINVAL);
- errno = 0;
- mt_fail(el_option(EL_PRINT_LEVEL, 3) == -1);
- mt_fail(errno == EINVAL);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_opt_colors(void)
-{
- mt_fok(el_option(EL_COLORS, 0));
- mt_fail(g_options.colors == 0);
- mt_fok(el_option(EL_COLORS, 1));
- mt_fail(g_options.colors == 1);
-
- mt_ferr(el_option(EL_COLORS, 2), EINVAL);
- mt_ferr(el_option(EL_COLORS, 3), EINVAL);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_opt_timestamp(void)
-{
- int i;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- for (i = EL_TS_OFF; i != EL_TS_ERROR; ++i)
- {
- mt_fok(el_option(EL_TS, i));
- mt_fail(g_options.timestamp == i);
- }
-
- mt_ferr(el_option(EL_TS, i), EINVAL);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_opt_timestamp_timer(void)
-{
- int i;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- for (i = EL_TS_TM_CLOCK; i != EL_TS_TM_ERROR; ++i)
- {
- mt_fok(el_option(EL_TS_TM, i));
- mt_fail(g_options.timestamp_timer == i);
- }
-
- mt_ferr(el_option(EL_TS_TM, i), EINVAL);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_ooption_test(void)
-{
- struct el_options opts;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_ooption(&opts, EL_TS_TM, EL_TS_TM_MONOTONIC);
- mt_fail(opts.timestamp_timer == EL_TS_TM_MONOTONIC);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void options_einval(void)
-{
- mt_ferr(el_option(10000, 5), EINVAL);
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
- / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
- / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
- \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
- /____/ /_/
- ========================================================================== */
-
-
-void el_options_test_group(void)
-{
- mt_run(options_init);
- mt_run(options_init_einval);
-
- mt_prepare_test = &test_prepare;
- mt_cleanup_test = &test_cleanup;
-
- mt_run(options_level_set);
- mt_run(options_output);
- mt_run(options_log_allowed);
- mt_run(options_opt_print_level);
- mt_run(options_opt_colors);
- mt_run(options_opt_timestamp);
- mt_run(options_opt_timestamp_timer);
- mt_run(options_ooption_test);
- mt_run(options_einval);
-}
+../src/el-options.c \ No newline at end of file
diff --git a/tst/el-perror.c b/tst/el-perror.c
index 0a9014f..cc73051 100644..120000
--- a/tst/el-perror.c
+++ b/tst/el-perror.c
@@ -1,173 +1 @@
-/* ==========================================================================
- Licensed under BSD 2clause license See LICENSE file for more information
- Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
- ========================================================================== */
-
-
-/* ==========================================================================
- _ __ __ ____ _ __
- (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
- / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
- / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
- /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
-
- ========================================================================== */
-
-
-#include <errno.h>
-#include <string.h>
-
-#include "mtest.h"
-#include "embedlog.h"
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- _ __ __
- _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
- | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
- | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
- |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
-
- ========================================================================== */
-
-
-mt_defs_ext();
-static char logbuf[1024 * 1024]; /* output simulation */
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- ____ __ _
- / __/__ __ ____ _____ / /_ (_)____ ____ _____
- / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
- / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
- /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
-
- ========================================================================== */
-
-
-/* ==========================================================================
- this is custom function that will be called instead of for example puts
- after el_print constructs message. We capture that message and simply
- append to logbuf, so we can analyze it later if everything is in order.
- ========================================================================== */
-
-
-static int print_to_buffer
-(
- const char *s
-)
-{
- strcat(logbuf, s);
- return 0;
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void test_prepare(void)
-{
- el_init();
- el_option(EL_CUSTOM_PUTS, print_to_buffer);
- el_option(EL_PRINT_LEVEL, 0);
- el_option(EL_OUT, EL_OUT_CUSTOM);
- logbuf[0] = '\0';
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void test_cleanup(void)
-{
- el_cleanup();
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ _____
- / __// _ \ / ___// __// ___/
- / /_ / __/(__ )/ /_ (__ )
- \__/ \___//____/ \__//____/
-
- ========================================================================== */
-
-
-static void perror_no_message(void)
-{
- errno = 1;
- el_perror(ELF, NULL);
- mt_fok(strcmp(logbuf, "errno num: 1, strerror: Operation not permitted\n"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void perror_user_message(void)
-{
- errno = 1;
- el_perror(ELF, "additional message");
- mt_fok(strcmp(logbuf, "additional message\n"
- "errno num: 1, strerror: Operation not permitted\n"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void perror_custom_options_user_message(void)
-{
- struct el_options opts;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_oinit(&opts);
- el_ooption(&opts, EL_CUSTOM_PUTS, print_to_buffer);
- el_ooption(&opts, EL_PRINT_LEVEL, 0);
- el_ooption(&opts, EL_OUT, EL_OUT_CUSTOM);
-
- errno = 1;
- el_operror(ELF, &opts, "additional message");
- mt_fok(strcmp(logbuf, "additional message\n"
- "errno num: 1, strerror: Operation not permitted\n"));
-
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
- / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
- / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
- \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
- /____/ /_/
- ========================================================================== */
-
-
-void el_perror_test_group(void)
-{
- mt_prepare_test = &test_prepare;
- mt_cleanup_test = &test_cleanup;
-
- mt_run(perror_no_message);
- mt_run(perror_user_message);
- mt_run(perror_custom_options_user_message);
-}
+../src/el-perror.c \ No newline at end of file
diff --git a/tst/el-pmemory.c b/tst/el-pmemory.c
index da1c17e..5dcc35f 100644..120000
--- a/tst/el-pmemory.c
+++ b/tst/el-pmemory.c
@@ -1,309 +1 @@
-/* ==========================================================================
- Licensed under BSD 2clause license See LICENSE file for more information
- Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
- ========================================================================== */
-
-
-/* ==========================================================================
- _ __ __ ____ _ __
- (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
- / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
- / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
- /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
-
- ========================================================================== */
-
-
-#include <errno.h>
-#include <string.h>
-
-#include "mtest.h"
-#include "embedlog.h"
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- _ __ __
- _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
- | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
- | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
- |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
-
- ========================================================================== */
-
-
-mt_defs_ext();
-static char logbuf[1024 * 1024]; /* output simulation */
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- ____ __ _
- / __/__ __ ____ _____ / /_ (_)____ ____ _____
- / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
- / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
- /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
-
- ========================================================================== */
-
-
-/* ==========================================================================
- this is custom function that will be called instead of for example puts
- after el_print constructs message. We capture that message and simply
- append to logbuf, so we can analyze it later if everything is in order.
- ========================================================================== */
-
-
-static int print_to_buffer
-(
- const char *s
-)
-{
- strcat(logbuf, s);
- return 0;
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void test_prepare(void)
-{
- el_init();
- el_option(EL_CUSTOM_PUTS, print_to_buffer);
- el_option(EL_PRINT_LEVEL, 0);
- el_option(EL_OUT, EL_OUT_CUSTOM);
- logbuf[0] = '\0';
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void test_cleanup(void)
-{
- el_cleanup();
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ _____
- / __// _ \ / ___// __// ___/
- / /_ / __/(__ )/ /_ (__ )
- \__/ \___//____/ \__//____/
-
- ========================================================================== */
-
-
-static void pmemory_one_byte(void)
-{
- static const char c = 'a';
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_pmemory(ELI, &c, sizeof(c));
- mt_fok(strcmp(logbuf,
-"------ ----------------------------------------------- ----------------\n"
-"offset hex ascii\n"
-"------ ----------------------------------------------- ----------------\n"
-"0x0000 61 a\n"
-"------ ----------------------------------------------- ----------------\n"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void pmemory_one_line_not_full(void)
-{
- static const char *s = "test string";
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- el_pmemory(ELI, s, strlen(s));
- mt_fok(strcmp(logbuf,
-"------ ----------------------------------------------- ----------------\n"
-"offset hex ascii\n"
-"------ ----------------------------------------------- ----------------\n"
-"0x0000 74 65 73 74 20 73 74 72 69 6e 67 test string\n"
-"------ ----------------------------------------------- ----------------\n"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void pmemory_one_line_full(void)
-{
- static const char *s = "qwertyuiopasdfgh";
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_pmemory(ELI, s, strlen(s));
- mt_fok(strcmp(logbuf,
-"------ ----------------------------------------------- ----------------\n"
-"offset hex ascii\n"
-"------ ----------------------------------------------- ----------------\n"
-"0x0000 71 77 65 72 74 79 75 69 6f 70 61 73 64 66 67 68 qwertyuiopasdfgh\n"
-"------ ----------------------------------------------- ----------------\n"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void pmemory_two_line_not_full(void)
-{
- static const char *s = "first line i am and i am 2";
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_pmemory(ELI, s, strlen(s));
- mt_fok(strcmp(logbuf,
-"------ ----------------------------------------------- ----------------\n"
-"offset hex ascii\n"
-"------ ----------------------------------------------- ----------------\n"
-"0x0000 66 69 72 73 74 20 6c 69 6e 65 20 69 20 61 6d 20 first line i am \n"
-"0x0010 61 6e 64 20 69 20 61 6d 20 32 and i am 2\n"
-"------ ----------------------------------------------- ----------------\n"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void pmemory_two_line_full(void)
-{
- static const char *s = "first line i am and i am 2nd lin";
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_pmemory(ELI, s, strlen(s));
- mt_fok(strcmp(logbuf,
-"------ ----------------------------------------------- ----------------\n"
-"offset hex ascii\n"
-"------ ----------------------------------------------- ----------------\n"
-"0x0000 66 69 72 73 74 20 6c 69 6e 65 20 69 20 61 6d 20 first line i am \n"
-"0x0010 61 6e 64 20 69 20 61 6d 20 32 6e 64 20 6c 69 6e and i am 2nd lin\n"
-"------ ----------------------------------------------- ----------------\n"));
-}
-
-
-static void pmemory_binary_data_with_nulls(void)
-{
- static const unsigned char data[] = {
- 0x05, 0x02, 0x10, 0x50, 0x53, 0x8f, 0xff, 0x3d,
- 0x00, 0x00, 0x4a, 0xab, 0xfc, 0x04, 0x00, 0xfa,
- 0xfd, 0xfa, 0x7f, 0x80 };
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_pmemory(ELI, data, sizeof(data));
- mt_fok(strcmp(logbuf,
-"------ ----------------------------------------------- ----------------\n"
-"offset hex ascii\n"
-"------ ----------------------------------------------- ----------------\n"
-"0x0000 05 02 10 50 53 8f ff 3d 00 00 4a ab fc 04 00 fa ...PS..=..J.....\n"
-"0x0010 fd fa 7f 80 ....\n"
-"------ ----------------------------------------------- ----------------\n"));
-}
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void pmemory_print_ascii_table(void)
-{
- char ascii[128 + 1];
- int i;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- for (i = 0; i != 0x80; ++i)
- {
- ascii[i] = (char)i;
- }
-
- ascii[i] = '\0';
-
- el_pmemory(ELI, ascii, sizeof(ascii) - 1);
- mt_fok(strcmp(logbuf,
-"------ ----------------------------------------------- ----------------\n"
-"offset hex ascii\n"
-"------ ----------------------------------------------- ----------------\n"
-"0x0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n"
-"0x0010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................\n"
-"0x0020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !\"#$%&'()*+,-./\n"
-"0x0030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?\n"
-"0x0040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO\n"
-"0x0050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\\]^_\n"
-"0x0060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno\n"
-"0x0070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.\n"
-"------ ----------------------------------------------- ----------------\n"));
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void pmemory_null_memory(void)
-{
- mt_ferr(el_pmemory(ELI, NULL, 10), EINVAL);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void pmemory_zero_size(void)
-{
- static const char *s = "some data";
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- mt_ferr(el_pmemory(ELI, s, 0), EINVAL);
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
- / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
- / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
- \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
- /____/ /_/
- ========================================================================== */
-
-
-void el_pmemory_test_group(void)
-{
- mt_prepare_test = &test_prepare;
- mt_cleanup_test = &test_cleanup;
-
- mt_run(pmemory_one_byte);
- mt_run(pmemory_one_line_not_full);
- mt_run(pmemory_one_line_full);
- mt_run(pmemory_two_line_not_full);
- mt_run(pmemory_two_line_full);
- mt_run(pmemory_binary_data_with_nulls);
- mt_run(pmemory_print_ascii_table);
- mt_run(pmemory_null_memory);
- mt_run(pmemory_zero_size);
-}
+../src/el-pmemory.c \ No newline at end of file
diff --git a/tst/el-print.c b/tst/el-print.c
index 8bbe9d6..1b5a73a 100644..120000
--- a/tst/el-print.c
+++ b/tst/el-print.c
@@ -1,818 +1 @@
-/* ==========================================================================
- Licensed under BSD 2clause license See LICENSE file for more information
- Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
- ========================================================================== */
-
-
-/* ==========================================================================
- _ __ __ ____ _ __
- (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
- / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
- / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
- /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
-
- ========================================================================== */
-
-#include <rb.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-#include <libgen.h>
-
-#include "mtest.h"
-#include "stdlib.h"
-#include "embedlog.h"
-
-#include "config-priv.h"
-#include "el-options.h"
-
-
-/* ==========================================================================
- _ __ __
- ____ _____ (_)_ __ ____ _ / /_ ___ / /_ __ __ ____ ___ _____
- / __ \ / ___// /| | / // __ `// __// _ \ / __// / / // __ \ / _ \ / ___/
- / /_/ // / / / | |/ // /_/ // /_ / __/ / /_ / /_/ // /_/ // __/(__ )
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/ \__/ \__, // .___/ \___//____/
-/_/ /____//_/
-
- ========================================================================== */
-
-
-struct log_message
-{
- const char *file;
- size_t line;
- int level;
- const char *msg;
-};
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- _ __ __
- _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
- | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
- | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
- |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
-
- ========================================================================== */
-
-
-mt_defs_ext();
-static char logbuf[1024 * 1024]; /* output simulation */
-static struct rb *expected_logs; /* array of expected logs */
-
-
-/* ==========================================================================
- _ __
- ____ _____ (_)_ __ ____ _ / /_ ___
- / __ \ / ___// /| | / // __ `// __// _ \
- / /_/ // / / / | |/ // /_/ // /_ / __/
- / .___//_/ /_/ |___/ \__,_/ \__/ \___/
- /_/
- ____ __ _
- / __/__ __ ____ _____ / /_ (_)____ ____ _____
- / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
- / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
- /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
-
- ========================================================================== */
-
-
-/* ==========================================================================
- this is custom function that will be called instead of for example puts,
- after el_print constructs message. We capture that message and simply
- append to logbuf, so we can analyze it later if everything is in order.
- ========================================================================== */
-
-
-static int print_to_buffer
-(
- const char *s
-)
-{
- strcat(logbuf, s);
- return 0;
-}
-
-
-/* ==========================================================================
- Checks if el_print function prints everything in well-defined format.
- This function cross-checks logbuf buffer where el_print function prints
- message into, and expected_logs with raw information about what should
- be printed.
- ========================================================================== */
-
-
-static int print_check(void)
-{
-#define IS_DIGIT() if (!isdigit(*msg++)) return -1
-#define IS_CHAR(c) if (*msg++ != c) return -1
-
- static const char *levelstr = "facewnid";
- struct log_message expected;
- char *msg;
- char tmp[1024];
- int i;
- int slevel;
- size_t msglen;
- static const char *color[] =
- {
- "\e[91m", /* fatal light red */
- "\e[31m", /* alert red */
- "\e[95m", /* critical light magenta */
- "\e[35m", /* error magenta */
- "\e[93m", /* warning light yellow */
- "\e[92m", /* notice light green */
- "\e[32m", /* information green */
- "\e[34m", /* debug blue */
- "\e[0m" /* remove all formats */
- };
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- msg = logbuf;
- while (rb_read(expected_logs, &expected, 1) == 1)
- {
- slevel = expected.level > EL_DBG ? EL_DBG : expected.level;
-
- if (expected.level > g_options.level)
- {
- /*
- * log should not have been printed due to current log level
- * restriction. We just continue here, because if log was indeed
- * printed, next checks will fail anyway.
- */
-
- continue;
- }
-
- if (g_options.colors)
- {
- if (strncmp(msg, color[slevel], 5) != 0)
- {
- /*
- * no color information or el_print generated wrong color
- */
-
- return -1;
- }
-
- /*
- * move msg by 5 bytes - begging of color is always 5char long
- */
-
- msg += 5;
- }
-
- /*
- * check printing timestamp
- */
-
- if (g_options.timestamp == EL_TS_LONG)
- {
- IS_CHAR('[');
- IS_DIGIT();
- IS_DIGIT();
- IS_DIGIT();
- IS_DIGIT();
- IS_CHAR('-');
- IS_DIGIT();
- IS_DIGIT();
- IS_CHAR('-');
- IS_DIGIT();
- IS_DIGIT();
- IS_CHAR(' ');
- IS_DIGIT();
- IS_DIGIT();
- IS_CHAR(':');
- IS_DIGIT();
- IS_DIGIT();
- IS_CHAR(':');
- IS_DIGIT();
- IS_DIGIT();
- IS_CHAR('.');
-
- for (i = 0; i != 6; ++i)
- {
- IS_DIGIT();
- }
- IS_CHAR(']');
-
- }
- else if (g_options.timestamp == EL_TS_SHORT)
- {
- IS_CHAR('[');
- while (*msg != '.' )
- {
- IS_DIGIT();
- }
-
- ++msg; /* skip the '.' character */
-
- for (i = 0; i != 6; ++i)
- {
- IS_DIGIT();
- }
- IS_CHAR(']');
- }
- else if (g_options.timestamp == EL_TS_OFF)
- {
- /*
- * we check for nothing here
- */
- }
- else
- {
- /*
- * wrong timestamp option value
- */
-
- return -1;
- }
-
- /*
- * check printing file information
- */
-
- if (g_options.finfo && expected.file != NULL && expected.line != 0)
- {
- char expected_file[FILENAME_MAX + 1];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- IS_CHAR('[');
- i = 0;
-
- while (*msg != ':')
- {
- tmp[i] = *msg++;
- if (i++ == EL_FLEN_MAX)
- {
- /*
- * we didn't find ':' character withing maximum lenght
- * of file - file is too long
- */
-
- return -1;
- }
- }
-
- msg++; /* skip ':' character */
- tmp[i] = '\0';
- strcpy(expected_file, expected.file);
-
- if (strcmp(tmp, basename(expected_file)) != 0)
- {
- /*
- * file name in printed log is different than what we set
- */
-
- return -1;
- }
-
- i = 0;
-
- while (*msg != ']')
- {
- tmp[i] = *msg;
- if (i++ == EL_PRE_FINFO_LINE_MAX_LEN)
- {
- /*
- * file line lenght is too large, or ending ']' is missing
- */
-
- return -1;
- }
-
- /*
- * file line should be a number ;-)
- */
-
- IS_DIGIT();
-
- }
-
- msg++; /* skip ']' character */
- tmp[i] = '\0';
-
- if ((size_t)atoi(tmp) != expected.line)
- {
- /*
- * line number in printed log is different than what was set
- */
-
- return -1;
- }
- }
-
- if ((g_options.finfo && expected.file != NULL && expected.line != 0) ||
- g_options.timestamp != EL_TS_OFF)
- {
- /*
- * file info or timestamp information is enabled, in that case
- * we check for additional space between info and log message
- */
-
- if (*msg++ != ' ')
- {
- return -1;
- }
- }
-
- /*
- * check printing log level
- */
-
- if (g_options.print_log_level)
- {
- if (*msg++ != levelstr[slevel])
- {
- return -1;
- }
-
- if (*msg++ != '/')
- {
- return -1;
- }
- }
-
- msglen = strlen(expected.msg);
-
- if (strncmp(msg, expected.msg, msglen) != 0)
- {
- return -1;
- }
-
- msg += msglen;
-
- if (g_options.colors)
- {
- if (strncmp(msg, color[8], 4) != 0)
- {
- /*
- * expected end of color, got some shit
- */
-
- return -1;
- }
-
- /*
- * end of color is always 4 bytes long
- */
-
- msg += 4;
- }
-
- if (*msg != '\n')
- {
- /*
- * all logs should be ended with new line
- */
-
- return -1;
- }
-
- /*
- * set msg to point to next message
- */
-
- ++msg;
- }
-
- return 0;
-
-#undef IS_CHAR
-#undef IS_DIGIT
-}
-
-
-/* ==========================================================================
- adds log to array of expected logs and then sends passed log message
- into el_print
- ========================================================================== */
-
-
-static void add_log
-(
- const char *file,
- size_t line,
- enum el_level level,
- const char *msg
-)
-{
- struct log_message expected;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- expected.file = file;
- expected.line = line;
- expected.level = level;
- expected.msg = msg;
- rb_write(expected_logs, &expected, 1);
- el_print(file, line, level, msg);
-}
-
-
-/* ==========================================================================
- Called before every test, initializes embedlog to known state, and
- allocates memory for expected_logs buffer
- ========================================================================== */
-
-
-static void test_prepare(void)
-{
- el_init();
- el_option(EL_CUSTOM_PUTS, print_to_buffer);
- el_option(EL_PRINT_LEVEL, 0);
- el_option(EL_OUT, EL_OUT_CUSTOM);
- memset(logbuf, 0, sizeof(logbuf));
- expected_logs = rb_new(1024, sizeof(struct log_message),
- O_NONTHREAD | O_NONBLOCK);
-}
-
-
-/* ==========================================================================
- Called after every test. Frees all memory allocated by test_prepare
- ========================================================================== */
-
-
-static void test_cleanup(void)
-{
- el_cleanup();
- rb_destroy(expected_logs);
-}
-
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ _____
- / __// _ \ / ___// __// ___/
- / /_ / __/(__ )/ /_ (__ )
- \__/ \___//____/ \__//____/
-
- ========================================================================== */
-
-
-static void print_simple_message(void)
-{
- add_log(ELF, "print_simple_message");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_simple_multiple_message(void)
-{
- add_log(ELF, "print_simple_multiple_message first");
- add_log(ELF, "print_simple_multiple_message second");
- add_log(ELF, "print_simple_multiple_message third");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_log_level(void)
-{
- el_option(EL_PRINT_LEVEL, 1);
- el_option(EL_LEVEL, EL_DBG);
- add_log(ELF, "print_log_level fatal message");
- add_log(ELA, "print_log_level alert message");
- add_log(ELC, "print_log_level critical message");
- add_log(ELE, "print_log_level error message");
- add_log(ELW, "print_log_level warning message");
- add_log(ELN, "print_log_level notice message");
- add_log(ELI, "print_log_level info message");
- add_log(ELD, "print_log_level debug message");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_colorful_output(void)
-{
- el_option(EL_COLORS, 1);
- el_option(EL_LEVEL, EL_DBG + 2);
- add_log(ELF, "print_colorful_output fatal message");
- add_log(ELA, "print_colorful_output alert message");
- add_log(ELC, "print_colorful_output critical message");
- add_log(ELE, "print_colorful_output error message");
- add_log(ELW, "print_colorful_output warning message");
- add_log(ELN, "print_colorful_output notice message");
- add_log(ELI, "print_colorful_output info message");
- add_log(ELD, "print_colorful_output debug message");
- add_log(ELD + 1, "print_colorful_output debug + 1 message");
- add_log(ELD + 2, "print_colorful_output debug + 2 message");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_custom_log_level(void)
-{
- el_option(EL_PRINT_LEVEL, 1);
- el_option(EL_LEVEL, EL_DBG + 5);
- add_log(ELD + 4, "print_custom_log_level custom debug 4");
- add_log(ELD + 5, "print_custom_log_level custom debug 5");
- add_log(ELD + 6, "print_custom_log_level custom debug 6");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_timestamp_short(void)
-{
- el_option(EL_TS, EL_TS_SHORT);
- add_log(ELF, "print_timestamp_short first");
- add_log(ELF, "print_timestamp_short second");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_timestamp_long(void)
-{
- el_option(EL_TS, EL_TS_LONG);
- add_log(ELF, "print_timestamp_long first");
- add_log(ELF, "print_timestamp_long second");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_finfo(void)
-{
- el_option(EL_FINFO, 1);
- add_log(ELF, "print_finfo first");
- add_log(ELF, "print_finfo second");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_different_clocks(void)
-{
- int i;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- for (i = EL_TS_TM_CLOCK; i != EL_TS_TM_ERROR; ++i)
- {
- test_prepare();
- el_option(EL_TS_TM, i);
- el_option(EL_TS, EL_TS_LONG);
- add_log(ELI, "clock test");
- mt_fok(print_check());
- test_cleanup();
- }
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_mix_of_everything(void)
-{
- int level;
- int timestamp;
- int printlevel;
- int finfo;
- int colors;
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- for (level = EL_FATAL; level <= EL_DBG; ++level)
- for (timestamp = EL_TS_OFF; timestamp != EL_TS_ERROR; ++timestamp)
- for (printlevel = 0; printlevel <= 1; ++printlevel)
- for (finfo = 0; finfo <= 1; ++finfo)
- for (colors = 0; colors <= 1; ++colors)
- {
- test_prepare();
- el_option(EL_LEVEL, level);
- el_option(EL_TS, timestamp);
- el_option(EL_PRINT_LEVEL, printlevel);
- el_option(EL_FINFO, finfo);
- el_option(EL_COLORS, colors);
-
- add_log(ELF, "fatal message");
- add_log(ELA, "alert message");
- add_log(ELC, "critical message");
- add_log(ELE, "error message");
- add_log(ELW, "warning message");
- add_log(ELN, "notice message");
- add_log(ELI, "info message");
- add_log(ELD, "debug message");
- mt_fok(print_check());
-
- test_cleanup();
- }
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_too_long_print_truncate(void)
-{
- char msg[EL_LOG_MAX + 3];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- memset(msg, 'a', sizeof(msg));
- msg[sizeof(msg) - 1] = '\0';
- msg[sizeof(msg) - 2] = '3';
- msg[sizeof(msg) - 3] = '2';
- msg[sizeof(msg) - 4] = '1';
- msg[sizeof(msg) - 4] = '0';
-
- add_log(ELI, "not truncated");
- add_log(ELI, msg);
-
- /*
- * while el_print will make copy of msg, our test print_check function
- * will just use pointer to our msg here, and since we expect message to
- * be truncated, we truncate it here and print_check will take this
- * truncated message as expected one.
- */
-
- msg[sizeof(msg) - 3] = '\0';
-
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_truncate_with_date(void)
-{
- char msg[EL_LOG_MAX + 3];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_option(EL_TS, EL_TS_LONG);
- memset(msg, 'a', sizeof(msg));
- msg[sizeof(msg) - 1] = '\0';
- msg[sizeof(msg) - 2] = '3';
- msg[sizeof(msg) - 3] = '2';
- msg[sizeof(msg) - 4] = '1';
- msg[sizeof(msg) - 4] = '0';
-
- add_log(ELI, "not truncated");
- add_log(ELI, msg);
-
- msg[sizeof(msg) - 3] = '\0';
-
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_truncate_with_all_options(void)
-{
- char msg[EL_LOG_MAX + 3];
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
-
- el_option(EL_TS, EL_TS_LONG);
- el_option(EL_FINFO, 1);
- el_option(EL_PRINT_LEVEL, 1);
- memset(msg, 'a', sizeof(msg));
- msg[sizeof(msg) - 1] = '\0';
- msg[sizeof(msg) - 2] = '3';
- msg[sizeof(msg) - 3] = '2';
- msg[sizeof(msg) - 4] = '1';
- msg[sizeof(msg) - 4] = '0';
-
- add_log(ELI, "not truncated");
- add_log(ELI, msg);
-
- msg[sizeof(msg) - 3] = '\0';
-
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_with_no_output_available(void)
-{
- el_option(EL_OUT, EL_OUT_NONE);
- mt_ferr(el_print(ELI, "i'll be back"), ENODEV);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_level_not_high_enough(void)
-{
- mt_ferr(el_print(ELD, "i won't be printed"), ERANGE);
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_finfo_path(void)
-{
- el_option(EL_FINFO, 1);
- add_log("source/code/file.c", 10, EL_ALERT, "some message");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_nofinfo(void)
-{
- el_option(EL_FINFO, 1);
- add_log(NULL, 0, EL_ALERT, "no file info");
- mt_fok(print_check());
-}
-
-
-/* ==========================================================================
- ========================================================================== */
-
-
-static void print_null(void)
-{
- mt_ferr(el_print(ELA, NULL), EINVAL);
-}
-
-/* ==========================================================================
- __ __
- / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
- / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
- / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
- \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
- /____/ /_/
- ========================================================================== */
-
-
-void el_print_test_group(void)
-{
- mt_run(print_different_clocks);
- mt_run(print_mix_of_everything);
-
- mt_prepare_test = &test_prepare;
- mt_cleanup_test = &test_cleanup;
-
- mt_run(print_simple_message);
- mt_run(print_simple_multiple_message);
- mt_run(print_log_level);
- mt_run(print_colorful_output);
- mt_run(print_custom_log_level);
- mt_run(print_timestamp_short);
- mt_run(print_timestamp_long);
- mt_run(print_finfo);
- mt_run(print_too_long_print_truncate);
- mt_run(print_truncate_with_date);
- mt_run(print_truncate_with_all_options);
- mt_run(print_with_no_output_available);
- mt_run(print_level_not_high_enough);
- mt_run(print_finfo_path);
- mt_run(print_nofinfo);
- mt_run(print_null);
-}
+../src/el-print.c \ No newline at end of file
diff --git a/tst/el-puts.c b/tst/el-puts.c
new file mode 120000
index 0000000..774e523
--- /dev/null
+++ b/tst/el-puts.c
@@ -0,0 +1 @@
+../src/el-puts.c \ No newline at end of file
diff --git a/tst/snprintf.c b/tst/snprintf.c
new file mode 120000
index 0000000..52193de
--- /dev/null
+++ b/tst/snprintf.c
@@ -0,0 +1 @@
+../src/snprintf.c \ No newline at end of file
diff --git a/tst/test-el-file.c b/tst/test-el-file.c
new file mode 100644
index 0000000..a74b113
--- /dev/null
+++ b/tst/test-el-file.c
@@ -0,0 +1,1155 @@
+/* ==========================================================================
+ Licensed under BSD 2clause license See LICENSE file for more information
+ Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
+ ========================================================================== */
+
+
+/* ==========================================================================
+ _ __ __ ____ _ __
+ (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
+ / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
+ / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
+ /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
+
+ ========================================================================== */
+
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <errno.h>
+
+#include "mtest.h"
+#include "embedlog.h"
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ _ __ __
+ _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
+ | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
+ | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
+ |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
+
+ ========================================================================== */
+
+
+#define WORKDIR "/tmp/embedlog-tests"
+#define s9 "123456789"
+#define s8 "qwertyui"
+#define s5 "qwert"
+#define s3 "asd"
+mt_defs_ext();
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ ____ __ _
+ / __/__ __ ____ _____ / /_ (_)____ ____ _____
+ / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
+ / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
+ /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
+
+ ========================================================================== */
+
+
+static int file_check
+(
+ const char *f,
+ const char *s
+)
+{
+ char fc[128];
+ int fd;
+ ssize_t r;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ fd = open(f, O_RDONLY);
+ r = read(fd, fc, sizeof(fc));
+ close(fd);
+
+ fc[r] = '\0';
+ if(strcmp(s, fc) != 0)
+ {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/* ==========================================================================
+
+ ========================================================================== */
+
+
+static void test_prepare(void)
+{
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 0);
+ el_option(EL_FNAME, WORKDIR"/log");
+
+}
+
+
+/* ==========================================================================
+
+ ========================================================================== */
+
+
+static void test_cleanup(void)
+{
+ int i;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ /*
+ * remove any file that might have been created during tests. We ignore
+ * unlink return code, as we expected that some files won't exist, as in
+ * are not needed by tests and thus are not created
+ */
+
+ unlink(WORKDIR"/log");
+ unlink(WORKDIR"/log-another");
+
+ for (i = 0; i != 5; ++i)
+ {
+ char path1[PATH_MAX] = WORKDIR"/log.";
+ char path2[PATH_MAX] = WORKDIR"/log-another.";
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+ path1[strlen(path1)] = '0' + i;
+ path2[strlen(path2)] = '0' + i;
+ unlink(path1);
+ unlink(path2);
+ }
+
+ el_cleanup();
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ _____
+ / __// _ \ / ___// __// ___/
+ / /_ / __/(__ )/ /_ (__ )
+ \__/ \___//____/ \__//____/
+
+ ========================================================================== */
+
+
+static void file_single_message(void)
+{
+ el_puts(s9);
+ mt_fok(file_check(WORKDIR"/log", s9));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_multi_message(void)
+{
+ el_puts(s9);
+ el_puts(s8);
+ el_puts(s5);
+ mt_fok(file_check(WORKDIR"/log", s9 s8 s5));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_reopen(void)
+{
+ el_puts(s9);
+ el_cleanup();
+
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 0);
+ el_option(EL_FNAME, WORKDIR"/log");
+
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log", s9 s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_reopen_different_file(void)
+{
+ el_puts(s9);
+ el_cleanup();
+
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 0);
+ el_option(EL_FNAME, WORKDIR"/log-another");
+
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log", s9));
+ mt_fok(file_check(WORKDIR"/log-another", s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_unexpected_third_party_delete(void)
+{
+ el_puts(s9);
+ unlink(WORKDIR"/log");
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log", s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_filename_too_long(void)
+{
+ char path[NAME_MAX + 1 + 1];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ memset(path, 'a', sizeof(path));
+ path[sizeof(path) - 1] = '\0';
+ mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_path_too_long(void)
+{
+ char path[PATH_MAX + 2];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ memset(path, 'a', sizeof(path));
+ path[0] = '/';
+ path[sizeof(path) - 5] = '/';
+ path[sizeof(path) - 4] = 'f';
+ path[sizeof(path) - 4] = 'i';
+ path[sizeof(path) - 3] = 'l';
+ path[sizeof(path) - 2] = 'e';
+ path[sizeof(path) - 1] = '\0';
+ mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_print_without_init(void)
+{
+ mt_ferr(el_puts("whatev..."), ENODEV);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_print_after_cleanup(void)
+{
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 0);
+ el_option(EL_FNAME, WORKDIR"/log");
+ el_cleanup();
+ mt_ferr(el_puts("whatev"), ENODEV);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_print_without_setting_file(void)
+{
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 0);
+ mt_ferr(el_puts("no file set"), EBADF);
+ el_cleanup();
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_no_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s9);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_exact_print(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s8);
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s8 s8));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_overflow_but_no_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s9 s5 s5);
+ mt_fok(file_check(WORKDIR"/log.0", s9 s5 "qw"));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_overflow(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s9);
+ el_puts(s9);
+ el_puts(s3);
+ mt_fok(file_check(WORKDIR"/log.0", s9 s3));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_overflow_exact(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s5);
+ mt_fok(file_check(WORKDIR"/log.0", s5));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_reopen(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s5);
+
+ el_cleanup();
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_option(EL_FNAME, WORKDIR"/log");
+
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s5 s8));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_unexpected_third_party_remove(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s5);
+ el_puts(s8);
+ unlink(WORKDIR"/log.0");
+ el_puts(s3);
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s3 s8));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_change_size_up(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s9);
+ el_puts(s5);
+ el_option(EL_FROTATE_SIZE, 32);
+ el_puts(s9);
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s9 s5 s9 s8));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_1_change_size_down(void)
+{
+ el_option(EL_FROTATE_NUMBER, 1);
+ el_puts(s9);
+ el_option(EL_FROTATE_SIZE, 8);
+ el_puts(s5);
+ mt_fok(file_check(WORKDIR"/log.0", s5));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_no_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s9);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_exact_print(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s8);
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s8 s8));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_overflow_but_no_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s9 s5 s5);
+ mt_fok(file_check(WORKDIR"/log.0", s9 s5 "qw"));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_overflow(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s9);
+ el_puts(s9);
+ el_puts(s3);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+ mt_fok(file_check(WORKDIR"/log.1", s9 s3));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_overflow_exact(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s5);
+ mt_fok(file_check(WORKDIR"/log.0", s8 s8));
+ mt_fok(file_check(WORKDIR"/log.1", s5));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_reopen(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s9);
+ el_puts(s8);
+
+ el_cleanup();
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_option(EL_FNAME, WORKDIR"/log");
+
+ el_puts(s5);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+ mt_fok(file_check(WORKDIR"/log.1", s8 s5));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_unexpected_third_party_remove(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s5);
+ el_puts(s8);
+ unlink(WORKDIR"/log.0");
+ el_puts(s3);
+ el_puts(s8);
+ el_puts(s9);
+ mt_fok(file_check(WORKDIR"/log.0", s3 s8));
+ mt_fok(file_check(WORKDIR"/log.1", s9));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_change_size_up(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s9);
+ el_puts(s5);
+ el_puts(s9);
+ el_option(EL_FROTATE_SIZE, 32);
+ el_puts(s9);
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s9 s5));
+ mt_fok(file_check(WORKDIR"/log.1", s9 s9 s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_change_size_down(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s9);
+ el_puts(s9);
+ el_option(EL_FROTATE_SIZE, 8);
+ el_puts(s5);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+ mt_fok(file_check(WORKDIR"/log.1", s5));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_2_many_rotates(void)
+{
+ el_option(EL_FROTATE_NUMBER, 2);
+ el_puts(s9);
+ el_puts(s8);
+ el_puts(s5);
+ el_puts(s5);
+ el_puts(s3);
+ el_puts(s9);
+ mt_fok(file_check(WORKDIR"/log.0", s5 s3));
+ mt_fok(file_check(WORKDIR"/log.1", s9));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_no_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_puts(s9);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+ mt_fail(access(WORKDIR"/log.1", F_OK) == -1);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_exact_print_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s8 s8));
+ mt_fok(file_check(WORKDIR"/log.1", s8 s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_overflow_but_no_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s9 s5 s5);
+ mt_fok(file_check(WORKDIR"/log.0", s8 s8));
+ mt_fok(file_check(WORKDIR"/log.1", s9 s5 "qw"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_overflow(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_puts(s9);
+ el_puts(s9);
+ el_puts(s3);
+ el_puts(s3);
+ el_puts(s8);
+ el_puts(s5);
+ el_puts(s9);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+ mt_fok(file_check(WORKDIR"/log.1", s9 s3 s3));
+ mt_fok(file_check(WORKDIR"/log.2", s8 s5));
+ mt_fok(file_check(WORKDIR"/log.3", s9));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_overflow_exact(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s8);
+ el_puts(s5);
+ mt_fok(file_check(WORKDIR"/log.0", s8 s8));
+ mt_fok(file_check(WORKDIR"/log.1", s8 s8));
+ mt_fok(file_check(WORKDIR"/log.2", s5));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_reopen(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+
+ el_puts(s9);
+ el_puts(s9);
+ el_puts(s3);
+ el_puts(s3);
+ el_puts(s8);
+ el_puts(s5);
+
+ el_cleanup();
+ el_init();
+ el_option(EL_OUT, EL_OUT_FILE);
+ el_option(EL_FROTATE_SIZE, 16);
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_option(EL_FNAME, WORKDIR"/log");
+
+ el_puts(s9);
+ el_puts(s8);
+ mt_fok(file_check(WORKDIR"/log.0", s9));
+ mt_fok(file_check(WORKDIR"/log.1", s9 s3 s3));
+ mt_fok(file_check(WORKDIR"/log.2", s8 s5));
+ mt_fok(file_check(WORKDIR"/log.3", s9));
+ mt_fok(file_check(WORKDIR"/log.4", s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_hole_in_log_rotate(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_option(EL_FROTATE_SIZE, 3);
+ el_puts("qaz");
+ el_puts("wsx");
+ el_puts("edc");
+ el_puts("rfv");
+ el_puts("tgb");
+
+ mt_fok(file_check(WORKDIR"/log.0", "qaz"));
+ mt_fok(file_check(WORKDIR"/log.1", "wsx"));
+ mt_fok(file_check(WORKDIR"/log.2", "edc"));
+ mt_fok(file_check(WORKDIR"/log.3", "rfv"));
+ mt_fok(file_check(WORKDIR"/log.4", "tgb"));
+
+ unlink(WORKDIR"/log.1");
+ unlink(WORKDIR"/log.4");
+
+ el_puts("123");
+
+ mt_fok(file_check(WORKDIR"/log.0", "qaz"));
+ mt_fok(file_check(WORKDIR"/log.1", "edc"));
+ mt_fok(file_check(WORKDIR"/log.2", "rfv"));
+ mt_fok(file_check(WORKDIR"/log.4", "123"));
+
+ el_puts("456");
+
+ mt_fok(file_check(WORKDIR"/log.0", "edc"));
+ mt_fok(file_check(WORKDIR"/log.1", "rfv"));
+ mt_fok(file_check(WORKDIR"/log.3", "123"));
+ mt_fok(file_check(WORKDIR"/log.4", "456"));
+
+ el_puts("789");
+
+ mt_fok(file_check(WORKDIR"/log.0", "rfv"));
+ mt_fok(file_check(WORKDIR"/log.2", "123"));
+ mt_fok(file_check(WORKDIR"/log.3", "456"));
+ mt_fok(file_check(WORKDIR"/log.4", "789"));
+
+ el_puts("qwe");
+
+ mt_fok(file_check(WORKDIR"/log.0", "rfv"));
+ mt_fok(file_check(WORKDIR"/log.1", "123"));
+ mt_fok(file_check(WORKDIR"/log.2", "456"));
+ mt_fok(file_check(WORKDIR"/log.3", "789"));
+ mt_fok(file_check(WORKDIR"/log.4", "qwe"));
+
+ el_puts("asd");
+
+ mt_fok(file_check(WORKDIR"/log.0", "123"));
+ mt_fok(file_check(WORKDIR"/log.1", "456"));
+ mt_fok(file_check(WORKDIR"/log.2", "789"));
+ mt_fok(file_check(WORKDIR"/log.3", "qwe"));
+ mt_fok(file_check(WORKDIR"/log.4", "asd"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_5_rename_file_halfway(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ el_option(EL_FROTATE_SIZE, 3);
+ el_puts("qaz");
+ el_puts("wsx");
+ el_puts("edc");
+ el_puts("rfv");
+ el_puts("tgb");
+
+ el_option(EL_FNAME, WORKDIR"/log-another");
+
+ el_puts("123");
+ el_puts("456");
+ el_puts("789");
+ el_puts("qwe");
+ el_puts("asd");
+
+ mt_fok(file_check(WORKDIR"/log.0", "qaz"));
+ mt_fok(file_check(WORKDIR"/log.1", "wsx"));
+ mt_fok(file_check(WORKDIR"/log.2", "edc"));
+ mt_fok(file_check(WORKDIR"/log.3", "rfv"));
+ mt_fok(file_check(WORKDIR"/log.4", "tgb"));
+
+ mt_fok(file_check(WORKDIR"/log-another.0", "123"));
+ mt_fok(file_check(WORKDIR"/log-another.1", "456"));
+ mt_fok(file_check(WORKDIR"/log-another.2", "789"));
+ mt_fok(file_check(WORKDIR"/log-another.3", "qwe"));
+ mt_fok(file_check(WORKDIR"/log-another.4", "asd"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_no_dir_for_logs(void)
+{
+ mt_ferr(el_option(EL_FNAME, "/tmp/i-dont/exist"), ENOENT);
+ mt_ferr(el_puts("whatever"), EBADF);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_dir_removed_after_open_then_created_back_again(void)
+{
+ mt_fok(el_puts(s8));
+ unlink(WORKDIR"/log");
+ rmdir(WORKDIR);
+ mt_ferr(el_puts(s3), EBADF);
+ mkdir(WORKDIR, 0755);
+ mt_fok(el_puts(s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_dir_no_access(void)
+{
+ mkdir("/tmp/embedlog-no-write", 0555);
+ if (getuid() == 0)
+ {
+ /*
+ * root just doesn't give a fuck about no-write-permissions
+ */
+
+ mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
+ mt_fok(el_puts(s3));
+ mt_fok(file_check("/tmp/embedlog-no-write/log", s3));
+ }
+ else
+ {
+ mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
+ mt_ferr(el_puts(s3), EBADF);
+ }
+ unlink("/tmp/embedlog-no-write/log");
+ rmdir("/tmp/embedlog-no-write");
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_no_access_to_file(void)
+{
+ int fd;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ mkdir("/tmp/embedlog-no-write", 0755);
+ fd = open("/tmp/embedlog-no-write/log", O_CREAT, 0444);
+ close(fd);
+
+ if (getuid() == 0)
+ {
+ mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
+ mt_fok(el_puts(s5));
+ mt_fok(file_check("/tmp/embedlog-no-write/log", s5));
+ }
+ else
+ {
+ mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
+ mt_ferr(el_puts("whatever"), EBADF);
+ }
+ unlink("/tmp/embedlog-no-write/log");
+ rmdir("/tmp/embedlog-no-write");
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_no_dir_for_logs(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ mt_ferr(el_option(EL_FNAME, "/tmp/i-dont/exist"), ENOENT);
+ mt_ferr(el_puts("whatever"), EBADF);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_dir_removed_after_open_then_created_back_again(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ mt_fok(el_puts(s8));
+ mt_fok(el_puts(s8));
+ mt_fok(el_puts(s8));
+ mt_fok(el_puts(s8));
+ mt_fok(el_puts(s8));
+ unlink(WORKDIR"/log");
+ unlink(WORKDIR"/log.0");
+ unlink(WORKDIR"/log.1");
+ unlink(WORKDIR"/log.2");
+ rmdir(WORKDIR);
+ mt_ferr(el_puts(s3), EBADF);
+ mkdir(WORKDIR, 0755);
+ mt_fok(el_puts(s8));
+ mt_fok(el_puts(s5));
+
+ mt_fok(file_check(WORKDIR"/log.2", s8 s5));
+
+ mt_fok(el_puts(s8));
+ mt_fok(el_puts(s3));
+ mt_fok(el_puts(s5));
+
+ mt_fok(file_check(WORKDIR"/log.2", s8 s5));
+ mt_fok(file_check(WORKDIR"/log.3", s8 s3 s5));
+
+ mt_fok(el_puts(s9));
+ mt_fok(el_puts(s5));
+
+ mt_fok(file_check(WORKDIR"/log.2", s8 s5));
+ mt_fok(file_check(WORKDIR"/log.3", s8 s3 s5));
+ mt_fok(file_check(WORKDIR"/log.4", s9 s5));
+
+ mt_fok(el_puts(s3));
+ mt_fok(el_puts(s8));
+
+ mt_fok(file_check(WORKDIR"/log.1", s8 s5));
+ mt_fok(file_check(WORKDIR"/log.2", s8 s3 s5));
+ mt_fok(file_check(WORKDIR"/log.3", s9 s5));
+ mt_fok(file_check(WORKDIR"/log.4", s3 s8));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_dir_no_access(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ mkdir("/tmp/embedlog-no-write", 0555);
+
+ if (getuid() == 0)
+ {
+ mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
+ mt_fok(el_puts(s3));
+ mt_fok(file_check("/tmp/embedlog-no-write/log.0", s3));
+ }
+ else
+ {
+ mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
+ mt_ferr(el_puts(s3), EBADF);
+ }
+
+ unlink("/tmp/embedlog-no-write/log.0");
+ rmdir("/tmp/embedlog-no-write");
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_no_access_to_file(void)
+{
+ int fd;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_option(EL_FROTATE_NUMBER, 5);
+ mkdir("/tmp/embedlog-no-write", 0755);
+ fd = open("/tmp/embedlog-no-write/log.0", O_CREAT, 0444);
+ close(fd);
+
+ if (getuid() == 0)
+ {
+ mt_fok(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"));
+ mt_fok(el_puts(s8));
+ mt_fok(file_check("/tmp/embedlog-no-write/log.0", s8));
+ }
+ else
+ {
+ mt_ferr(el_option(EL_FNAME, "/tmp/embedlog-no-write/log"), EACCES);
+ mt_ferr(el_puts("whatever"), EBADF);
+ }
+
+ unlink("/tmp/embedlog-no-write/log.0");
+ rmdir("/tmp/embedlog-no-write");
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_filename_too_long(void)
+{
+ char path[NAME_MAX];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ memset(path, 'a', sizeof(path));
+ path[sizeof(path) - 1] = '\0';
+ el_option(EL_FROTATE_NUMBER, 5);
+ mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_path_too_long(void)
+{
+ char path[PATH_MAX + 2];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ memset(path, 'a', sizeof(path));
+ path[0] = '/';
+ path[sizeof(path) - 5] = '/';
+ path[sizeof(path) - 4] = 'f';
+ path[sizeof(path) - 4] = 'i';
+ path[sizeof(path) - 3] = 'l';
+ path[sizeof(path) - 2] = 'e';
+ path[sizeof(path) - 1] = '\0';
+ el_option(EL_FROTATE_NUMBER, 5);
+ mt_ferr(el_option(EL_FNAME, path), ENAMETOOLONG);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void file_rotate_fail(void)
+{
+ el_option(EL_FROTATE_NUMBER, 5);
+ mt_fok(el_puts(s8));
+ mt_fok(el_puts(s8));
+ unlink(WORKDIR"/log");
+ unlink(WORKDIR"/log.0");
+ rmdir(WORKDIR);
+ mt_ferr(el_puts(s3), ENOENT);
+ mkdir(WORKDIR, 0755);
+ mt_fok(el_puts(s8));
+
+ mt_fok(file_check(WORKDIR"/log.1", s8));
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
+ / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
+ / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
+ \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
+ /____/ /_/
+ ========================================================================== */
+
+
+void el_file_test_group(void)
+{
+ mkdir(WORKDIR, 0755);
+
+ mt_run(file_print_without_init);
+ mt_run(file_print_after_cleanup);
+ mt_run(file_print_without_setting_file);
+
+ mt_prepare_test = &test_prepare;
+ mt_cleanup_test = &test_cleanup;
+
+ mt_run(file_single_message);
+ mt_run(file_multi_message);
+ mt_run(file_reopen);
+ mt_run(file_reopen_different_file);
+ mt_run(file_unexpected_third_party_delete);
+ mt_run(file_filename_too_long);
+ mt_run(file_path_too_long);
+ mt_run(file_rotate_1_no_rotate);
+ mt_run(file_rotate_1_exact_print);
+ mt_run(file_rotate_1_overflow_but_no_rotate);
+ mt_run(file_rotate_1_overflow);
+ mt_run(file_rotate_1_overflow_exact);
+ mt_run(file_rotate_1_reopen);
+ mt_run(file_rotate_1_unexpected_third_party_remove);
+ mt_run(file_rotate_1_change_size_up);
+ mt_run(file_rotate_1_change_size_down);
+ mt_run(file_rotate_2_no_rotate);
+ mt_run(file_rotate_2_exact_print);
+ mt_run(file_rotate_2_overflow_but_no_rotate);
+ mt_run(file_rotate_2_overflow);
+ mt_run(file_rotate_2_overflow_exact);
+ mt_run(file_rotate_2_reopen);
+ mt_run(file_rotate_2_unexpected_third_party_remove);
+ mt_run(file_rotate_2_change_size_up);
+ mt_run(file_rotate_2_change_size_down);
+ mt_run(file_rotate_2_many_rotates);
+ mt_run(file_rotate_5_no_rotate);
+ mt_run(file_rotate_5_exact_print_rotate);
+ mt_run(file_rotate_5_overflow_but_no_rotate);
+ mt_run(file_rotate_5_overflow);
+ mt_run(file_rotate_5_overflow_exact);
+ mt_run(file_rotate_5_reopen);
+ mt_run(file_rotate_5_hole_in_log_rotate);
+ mt_run(file_rotate_5_rename_file_halfway);
+ mt_run(file_no_dir_for_logs);
+ mt_run(file_dir_removed_after_open_then_created_back_again);
+ mt_run(file_dir_no_access);
+ mt_run(file_no_access_to_file);
+ mt_run(file_rotate_no_dir_for_logs);
+ mt_run(file_rotate_dir_removed_after_open_then_created_back_again);
+ mt_run(file_rotate_dir_no_access);
+ mt_run(file_rotate_no_access_to_file);
+ mt_run(file_rotate_filename_too_long);
+ mt_run(file_rotate_path_too_long);
+ mt_run(file_rotate_fail);
+
+ rmdir(WORKDIR);
+}
diff --git a/tst/test-el-options.c b/tst/test-el-options.c
new file mode 100644
index 0000000..1e6fa85
--- /dev/null
+++ b/tst/test-el-options.c
@@ -0,0 +1,321 @@
+/* ==========================================================================
+ Licensed under BSD 2clause license See LICENSE file for more information
+ Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
+ ========================================================================== */
+
+/* ==========================================================================
+ _ __ __ ____ _ __
+ (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
+ / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
+ / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
+ /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
+
+ ========================================================================== */
+
+
+#include <string.h>
+#include <errno.h>
+
+#include "embedlog.h"
+#include "el-options.h"
+#include "mtest.h"
+#include "test-group-list.h"
+#include "config.h"
+
+
+/* ==========================================================================
+ __ __ __
+ ____ _ / /____ / /_ ____ _ / /
+ / __ `// // __ \ / __ \ / __ `// /
+ / /_/ // // /_/ // /_/ // /_/ // /
+ \__, //_/ \____//_.___/ \__,_//_/
+ /____/
+ _ __ __
+ _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
+ | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
+ | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
+ |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
+
+ ========================================================================== */
+
+
+mt_defs_ext(); /* external variables for mtest */
+extern struct el_options g_options; /* global embedlog options */
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ _ __ __
+ _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
+ | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
+ | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
+ |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
+
+ ========================================================================== */
+
+
+static void test_prepare(void)
+{
+ el_init();
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void test_cleanup(void)
+{
+ el_cleanup();
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ _____
+ / __// _ \ / ___// __// ___/
+ / /_ / __/(__ )/ /_ (__ )
+ \__/ \___//____/ \__//____/
+
+ ========================================================================== */
+
+
+static void options_init(void)
+{
+ struct el_options default_options; /* expected default options */
+ struct el_options options; /* custom options to init */
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ memset(&default_options, 0, sizeof(default_options));
+ default_options.outputs = 0;
+ default_options.level = EL_INFO;
+ default_options.colors = 0;
+ default_options.timestamp = EL_TS_OFF;
+ default_options.timestamp_timer = EL_TS_TM_CLOCK;
+ default_options.print_log_level = 1;
+ default_options.custom_puts = NULL;
+
+ default_options.finfo = 0;
+ default_options.frotate_number = 0;
+ default_options.fcurrent_rotate = 0;
+ default_options.frotate_size = 0;
+ default_options.fpos = 0;
+ default_options.file = NULL;
+ default_options.fname = NULL;
+
+ mt_fail(el_oinit(&options) == 0);
+ mt_fail(memcmp(&options, &default_options, sizeof(options)) == 0);
+ mt_fail(el_ocleanup(&options) == 0);
+
+ mt_fail(el_init() == 0);
+ mt_fail(memcmp(&g_options, &default_options, sizeof(default_options)) == 0);
+ mt_fail(el_cleanup() == 0);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_init_einval(void)
+{
+ errno = 0;
+ mt_fail(el_oinit(NULL) == -1);
+ mt_fail(errno == EINVAL);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_level_set(void)
+{
+ int i;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ for (i = 0; i != 32; ++i)
+ {
+ mt_fail(el_option(EL_LEVEL, i) == 0);
+ mt_fail(g_options.level == i);
+ }
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_output(void)
+{
+ int current_outputs;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+ current_outputs = 0;
+ mt_fok(el_option(EL_OUT, EL_OUT_STDERR));
+ mt_fail(g_options.outputs == EL_OUT_STDERR);
+
+ mt_fok(el_option(EL_OUT, (EL_OUT_STDERR | EL_OUT_FILE)));
+ mt_fail(g_options.outputs == (EL_OUT_STDERR | EL_OUT_FILE));
+
+ mt_ferr(el_option(EL_OUT, EL_OUT_ALL + 7), EINVAL);
+ mt_fail(g_options.outputs == (EL_OUT_STDERR | EL_OUT_FILE));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_log_allowed(void)
+{
+ g_options.level = EL_ERROR;
+ g_options.outputs = EL_OUT_STDERR;
+
+ mt_fail(el_log_allowed(&g_options, EL_FATAL) == 1);
+ mt_fail(el_log_allowed(&g_options, EL_ALERT) == 1);
+ mt_fail(el_log_allowed(&g_options, EL_CRIT) == 1);
+ mt_fail(el_log_allowed(&g_options, EL_ERROR) == 1);
+ mt_fail(el_log_allowed(&g_options, EL_WARN) == 0);
+ mt_fail(el_log_allowed(&g_options, EL_NOTICE) == 0);
+ mt_fail(el_log_allowed(&g_options, EL_INFO) == 0);
+ mt_fail(el_log_allowed(&g_options, EL_DBG) == 0);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_opt_print_level(void)
+{
+ mt_fail(el_option(EL_PRINT_LEVEL, 0) == 0);
+ mt_fail(g_options.print_log_level == 0);
+ mt_fail(el_option(EL_PRINT_LEVEL, 1) == 0);
+ mt_fail(g_options.print_log_level == 1);
+
+ errno = 0;
+ mt_fail(el_option(EL_PRINT_LEVEL, 2) == -1);
+ mt_fail(errno == EINVAL);
+ errno = 0;
+ mt_fail(el_option(EL_PRINT_LEVEL, 3) == -1);
+ mt_fail(errno == EINVAL);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_opt_colors(void)
+{
+ mt_fok(el_option(EL_COLORS, 0));
+ mt_fail(g_options.colors == 0);
+ mt_fok(el_option(EL_COLORS, 1));
+ mt_fail(g_options.colors == 1);
+
+ mt_ferr(el_option(EL_COLORS, 2), EINVAL);
+ mt_ferr(el_option(EL_COLORS, 3), EINVAL);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_opt_timestamp(void)
+{
+ int i;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ for (i = EL_TS_OFF; i != EL_TS_ERROR; ++i)
+ {
+ mt_fok(el_option(EL_TS, i));
+ mt_fail(g_options.timestamp == i);
+ }
+
+ mt_ferr(el_option(EL_TS, i), EINVAL);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_opt_timestamp_timer(void)
+{
+ int i;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ for (i = EL_TS_TM_CLOCK; i != EL_TS_TM_ERROR; ++i)
+ {
+ mt_fok(el_option(EL_TS_TM, i));
+ mt_fail(g_options.timestamp_timer == i);
+ }
+
+ mt_ferr(el_option(EL_TS_TM, i), EINVAL);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_ooption_test(void)
+{
+ struct el_options opts;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_ooption(&opts, EL_TS_TM, EL_TS_TM_MONOTONIC);
+ mt_fail(opts.timestamp_timer == EL_TS_TM_MONOTONIC);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void options_einval(void)
+{
+ mt_ferr(el_option(10000, 5), EINVAL);
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
+ / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
+ / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
+ \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
+ /____/ /_/
+ ========================================================================== */
+
+
+void el_options_test_group(void)
+{
+ mt_run(options_init);
+ mt_run(options_init_einval);
+
+ mt_prepare_test = &test_prepare;
+ mt_cleanup_test = &test_cleanup;
+
+ mt_run(options_level_set);
+ mt_run(options_output);
+ mt_run(options_log_allowed);
+ mt_run(options_opt_print_level);
+ mt_run(options_opt_colors);
+ mt_run(options_opt_timestamp);
+ mt_run(options_opt_timestamp_timer);
+ mt_run(options_ooption_test);
+ mt_run(options_einval);
+}
diff --git a/tst/test-el-perror.c b/tst/test-el-perror.c
new file mode 100644
index 0000000..0a9014f
--- /dev/null
+++ b/tst/test-el-perror.c
@@ -0,0 +1,173 @@
+/* ==========================================================================
+ Licensed under BSD 2clause license See LICENSE file for more information
+ Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
+ ========================================================================== */
+
+
+/* ==========================================================================
+ _ __ __ ____ _ __
+ (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
+ / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
+ / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
+ /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
+
+ ========================================================================== */
+
+
+#include <errno.h>
+#include <string.h>
+
+#include "mtest.h"
+#include "embedlog.h"
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ _ __ __
+ _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
+ | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
+ | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
+ |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
+
+ ========================================================================== */
+
+
+mt_defs_ext();
+static char logbuf[1024 * 1024]; /* output simulation */
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ ____ __ _
+ / __/__ __ ____ _____ / /_ (_)____ ____ _____
+ / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
+ / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
+ /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
+
+ ========================================================================== */
+
+
+/* ==========================================================================
+ this is custom function that will be called instead of for example puts
+ after el_print constructs message. We capture that message and simply
+ append to logbuf, so we can analyze it later if everything is in order.
+ ========================================================================== */
+
+
+static int print_to_buffer
+(
+ const char *s
+)
+{
+ strcat(logbuf, s);
+ return 0;
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void test_prepare(void)
+{
+ el_init();
+ el_option(EL_CUSTOM_PUTS, print_to_buffer);
+ el_option(EL_PRINT_LEVEL, 0);
+ el_option(EL_OUT, EL_OUT_CUSTOM);
+ logbuf[0] = '\0';
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void test_cleanup(void)
+{
+ el_cleanup();
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ _____
+ / __// _ \ / ___// __// ___/
+ / /_ / __/(__ )/ /_ (__ )
+ \__/ \___//____/ \__//____/
+
+ ========================================================================== */
+
+
+static void perror_no_message(void)
+{
+ errno = 1;
+ el_perror(ELF, NULL);
+ mt_fok(strcmp(logbuf, "errno num: 1, strerror: Operation not permitted\n"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void perror_user_message(void)
+{
+ errno = 1;
+ el_perror(ELF, "additional message");
+ mt_fok(strcmp(logbuf, "additional message\n"
+ "errno num: 1, strerror: Operation not permitted\n"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void perror_custom_options_user_message(void)
+{
+ struct el_options opts;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_oinit(&opts);
+ el_ooption(&opts, EL_CUSTOM_PUTS, print_to_buffer);
+ el_ooption(&opts, EL_PRINT_LEVEL, 0);
+ el_ooption(&opts, EL_OUT, EL_OUT_CUSTOM);
+
+ errno = 1;
+ el_operror(ELF, &opts, "additional message");
+ mt_fok(strcmp(logbuf, "additional message\n"
+ "errno num: 1, strerror: Operation not permitted\n"));
+
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
+ / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
+ / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
+ \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
+ /____/ /_/
+ ========================================================================== */
+
+
+void el_perror_test_group(void)
+{
+ mt_prepare_test = &test_prepare;
+ mt_cleanup_test = &test_cleanup;
+
+ mt_run(perror_no_message);
+ mt_run(perror_user_message);
+ mt_run(perror_custom_options_user_message);
+}
diff --git a/tst/test-el-pmemory.c b/tst/test-el-pmemory.c
new file mode 100644
index 0000000..da1c17e
--- /dev/null
+++ b/tst/test-el-pmemory.c
@@ -0,0 +1,309 @@
+/* ==========================================================================
+ Licensed under BSD 2clause license See LICENSE file for more information
+ Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
+ ========================================================================== */
+
+
+/* ==========================================================================
+ _ __ __ ____ _ __
+ (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
+ / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
+ / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
+ /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
+
+ ========================================================================== */
+
+
+#include <errno.h>
+#include <string.h>
+
+#include "mtest.h"
+#include "embedlog.h"
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ _ __ __
+ _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
+ | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
+ | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
+ |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
+
+ ========================================================================== */
+
+
+mt_defs_ext();
+static char logbuf[1024 * 1024]; /* output simulation */
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ ____ __ _
+ / __/__ __ ____ _____ / /_ (_)____ ____ _____
+ / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
+ / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
+ /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
+
+ ========================================================================== */
+
+
+/* ==========================================================================
+ this is custom function that will be called instead of for example puts
+ after el_print constructs message. We capture that message and simply
+ append to logbuf, so we can analyze it later if everything is in order.
+ ========================================================================== */
+
+
+static int print_to_buffer
+(
+ const char *s
+)
+{
+ strcat(logbuf, s);
+ return 0;
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void test_prepare(void)
+{
+ el_init();
+ el_option(EL_CUSTOM_PUTS, print_to_buffer);
+ el_option(EL_PRINT_LEVEL, 0);
+ el_option(EL_OUT, EL_OUT_CUSTOM);
+ logbuf[0] = '\0';
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void test_cleanup(void)
+{
+ el_cleanup();
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ _____
+ / __// _ \ / ___// __// ___/
+ / /_ / __/(__ )/ /_ (__ )
+ \__/ \___//____/ \__//____/
+
+ ========================================================================== */
+
+
+static void pmemory_one_byte(void)
+{
+ static const char c = 'a';
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_pmemory(ELI, &c, sizeof(c));
+ mt_fok(strcmp(logbuf,
+"------ ----------------------------------------------- ----------------\n"
+"offset hex ascii\n"
+"------ ----------------------------------------------- ----------------\n"
+"0x0000 61 a\n"
+"------ ----------------------------------------------- ----------------\n"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void pmemory_one_line_not_full(void)
+{
+ static const char *s = "test string";
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+ el_pmemory(ELI, s, strlen(s));
+ mt_fok(strcmp(logbuf,
+"------ ----------------------------------------------- ----------------\n"
+"offset hex ascii\n"
+"------ ----------------------------------------------- ----------------\n"
+"0x0000 74 65 73 74 20 73 74 72 69 6e 67 test string\n"
+"------ ----------------------------------------------- ----------------\n"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void pmemory_one_line_full(void)
+{
+ static const char *s = "qwertyuiopasdfgh";
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_pmemory(ELI, s, strlen(s));
+ mt_fok(strcmp(logbuf,
+"------ ----------------------------------------------- ----------------\n"
+"offset hex ascii\n"
+"------ ----------------------------------------------- ----------------\n"
+"0x0000 71 77 65 72 74 79 75 69 6f 70 61 73 64 66 67 68 qwertyuiopasdfgh\n"
+"------ ----------------------------------------------- ----------------\n"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void pmemory_two_line_not_full(void)
+{
+ static const char *s = "first line i am and i am 2";
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_pmemory(ELI, s, strlen(s));
+ mt_fok(strcmp(logbuf,
+"------ ----------------------------------------------- ----------------\n"
+"offset hex ascii\n"
+"------ ----------------------------------------------- ----------------\n"
+"0x0000 66 69 72 73 74 20 6c 69 6e 65 20 69 20 61 6d 20 first line i am \n"
+"0x0010 61 6e 64 20 69 20 61 6d 20 32 and i am 2\n"
+"------ ----------------------------------------------- ----------------\n"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void pmemory_two_line_full(void)
+{
+ static const char *s = "first line i am and i am 2nd lin";
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_pmemory(ELI, s, strlen(s));
+ mt_fok(strcmp(logbuf,
+"------ ----------------------------------------------- ----------------\n"
+"offset hex ascii\n"
+"------ ----------------------------------------------- ----------------\n"
+"0x0000 66 69 72 73 74 20 6c 69 6e 65 20 69 20 61 6d 20 first line i am \n"
+"0x0010 61 6e 64 20 69 20 61 6d 20 32 6e 64 20 6c 69 6e and i am 2nd lin\n"
+"------ ----------------------------------------------- ----------------\n"));
+}
+
+
+static void pmemory_binary_data_with_nulls(void)
+{
+ static const unsigned char data[] = {
+ 0x05, 0x02, 0x10, 0x50, 0x53, 0x8f, 0xff, 0x3d,
+ 0x00, 0x00, 0x4a, 0xab, 0xfc, 0x04, 0x00, 0xfa,
+ 0xfd, 0xfa, 0x7f, 0x80 };
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_pmemory(ELI, data, sizeof(data));
+ mt_fok(strcmp(logbuf,
+"------ ----------------------------------------------- ----------------\n"
+"offset hex ascii\n"
+"------ ----------------------------------------------- ----------------\n"
+"0x0000 05 02 10 50 53 8f ff 3d 00 00 4a ab fc 04 00 fa ...PS..=..J.....\n"
+"0x0010 fd fa 7f 80 ....\n"
+"------ ----------------------------------------------- ----------------\n"));
+}
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void pmemory_print_ascii_table(void)
+{
+ char ascii[128 + 1];
+ int i;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+ for (i = 0; i != 0x80; ++i)
+ {
+ ascii[i] = (char)i;
+ }
+
+ ascii[i] = '\0';
+
+ el_pmemory(ELI, ascii, sizeof(ascii) - 1);
+ mt_fok(strcmp(logbuf,
+"------ ----------------------------------------------- ----------------\n"
+"offset hex ascii\n"
+"------ ----------------------------------------------- ----------------\n"
+"0x0000 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f ................\n"
+"0x0010 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f ................\n"
+"0x0020 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f !\"#$%&'()*+,-./\n"
+"0x0030 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 0123456789:;<=>?\n"
+"0x0040 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO\n"
+"0x0050 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f PQRSTUVWXYZ[\\]^_\n"
+"0x0060 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f `abcdefghijklmno\n"
+"0x0070 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f pqrstuvwxyz{|}~.\n"
+"------ ----------------------------------------------- ----------------\n"));
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void pmemory_null_memory(void)
+{
+ mt_ferr(el_pmemory(ELI, NULL, 10), EINVAL);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void pmemory_zero_size(void)
+{
+ static const char *s = "some data";
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ mt_ferr(el_pmemory(ELI, s, 0), EINVAL);
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
+ / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
+ / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
+ \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
+ /____/ /_/
+ ========================================================================== */
+
+
+void el_pmemory_test_group(void)
+{
+ mt_prepare_test = &test_prepare;
+ mt_cleanup_test = &test_cleanup;
+
+ mt_run(pmemory_one_byte);
+ mt_run(pmemory_one_line_not_full);
+ mt_run(pmemory_one_line_full);
+ mt_run(pmemory_two_line_not_full);
+ mt_run(pmemory_two_line_full);
+ mt_run(pmemory_binary_data_with_nulls);
+ mt_run(pmemory_print_ascii_table);
+ mt_run(pmemory_null_memory);
+ mt_run(pmemory_zero_size);
+}
diff --git a/tst/test-el-print.c b/tst/test-el-print.c
new file mode 100644
index 0000000..8bbe9d6
--- /dev/null
+++ b/tst/test-el-print.c
@@ -0,0 +1,818 @@
+/* ==========================================================================
+ Licensed under BSD 2clause license See LICENSE file for more information
+ Author: Michał Łyszczek <michal.lyszczek@bofc.pl>
+ ========================================================================== */
+
+
+/* ==========================================================================
+ _ __ __ ____ _ __
+ (_)____ _____ / /__ __ ____/ /___ / __/(_)/ /___ _____
+ / // __ \ / ___// // / / // __ // _ \ / /_ / // // _ \ / ___/
+ / // / / // /__ / // /_/ // /_/ // __/ / __// // // __/(__ )
+ /_//_/ /_/ \___//_/ \__,_/ \__,_/ \___/ /_/ /_//_/ \___//____/
+
+ ========================================================================== */
+
+#include <rb.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <libgen.h>
+
+#include "mtest.h"
+#include "stdlib.h"
+#include "embedlog.h"
+
+#include "config-priv.h"
+#include "el-options.h"
+
+
+/* ==========================================================================
+ _ __ __
+ ____ _____ (_)_ __ ____ _ / /_ ___ / /_ __ __ ____ ___ _____
+ / __ \ / ___// /| | / // __ `// __// _ \ / __// / / // __ \ / _ \ / ___/
+ / /_/ // / / / | |/ // /_/ // /_ / __/ / /_ / /_/ // /_/ // __/(__ )
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/ \__/ \__, // .___/ \___//____/
+/_/ /____//_/
+
+ ========================================================================== */
+
+
+struct log_message
+{
+ const char *file;
+ size_t line;
+ int level;
+ const char *msg;
+};
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ _ __ __
+ _ __ ____ _ _____ (_)____ _ / /_ / /___ _____
+ | | / // __ `// ___// // __ `// __ \ / // _ \ / ___/
+ | |/ // /_/ // / / // /_/ // /_/ // // __/(__ )
+ |___/ \__,_//_/ /_/ \__,_//_.___//_/ \___//____/
+
+ ========================================================================== */
+
+
+mt_defs_ext();
+static char logbuf[1024 * 1024]; /* output simulation */
+static struct rb *expected_logs; /* array of expected logs */
+
+
+/* ==========================================================================
+ _ __
+ ____ _____ (_)_ __ ____ _ / /_ ___
+ / __ \ / ___// /| | / // __ `// __// _ \
+ / /_/ // / / / | |/ // /_/ // /_ / __/
+ / .___//_/ /_/ |___/ \__,_/ \__/ \___/
+ /_/
+ ____ __ _
+ / __/__ __ ____ _____ / /_ (_)____ ____ _____
+ / /_ / / / // __ \ / ___// __// // __ \ / __ \ / ___/
+ / __// /_/ // / / // /__ / /_ / // /_/ // / / /(__ )
+ /_/ \__,_//_/ /_/ \___/ \__//_/ \____//_/ /_//____/
+
+ ========================================================================== */
+
+
+/* ==========================================================================
+ this is custom function that will be called instead of for example puts,
+ after el_print constructs message. We capture that message and simply
+ append to logbuf, so we can analyze it later if everything is in order.
+ ========================================================================== */
+
+
+static int print_to_buffer
+(
+ const char *s
+)
+{
+ strcat(logbuf, s);
+ return 0;
+}
+
+
+/* ==========================================================================
+ Checks if el_print function prints everything in well-defined format.
+ This function cross-checks logbuf buffer where el_print function prints
+ message into, and expected_logs with raw information about what should
+ be printed.
+ ========================================================================== */
+
+
+static int print_check(void)
+{
+#define IS_DIGIT() if (!isdigit(*msg++)) return -1
+#define IS_CHAR(c) if (*msg++ != c) return -1
+
+ static const char *levelstr = "facewnid";
+ struct log_message expected;
+ char *msg;
+ char tmp[1024];
+ int i;
+ int slevel;
+ size_t msglen;
+ static const char *color[] =
+ {
+ "\e[91m", /* fatal light red */
+ "\e[31m", /* alert red */
+ "\e[95m", /* critical light magenta */
+ "\e[35m", /* error magenta */
+ "\e[93m", /* warning light yellow */
+ "\e[92m", /* notice light green */
+ "\e[32m", /* information green */
+ "\e[34m", /* debug blue */
+ "\e[0m" /* remove all formats */
+ };
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+ msg = logbuf;
+ while (rb_read(expected_logs, &expected, 1) == 1)
+ {
+ slevel = expected.level > EL_DBG ? EL_DBG : expected.level;
+
+ if (expected.level > g_options.level)
+ {
+ /*
+ * log should not have been printed due to current log level
+ * restriction. We just continue here, because if log was indeed
+ * printed, next checks will fail anyway.
+ */
+
+ continue;
+ }
+
+ if (g_options.colors)
+ {
+ if (strncmp(msg, color[slevel], 5) != 0)
+ {
+ /*
+ * no color information or el_print generated wrong color
+ */
+
+ return -1;
+ }
+
+ /*
+ * move msg by 5 bytes - begging of color is always 5char long
+ */
+
+ msg += 5;
+ }
+
+ /*
+ * check printing timestamp
+ */
+
+ if (g_options.timestamp == EL_TS_LONG)
+ {
+ IS_CHAR('[');
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_CHAR('-');
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_CHAR('-');
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_CHAR(' ');
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_CHAR(':');
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_CHAR(':');
+ IS_DIGIT();
+ IS_DIGIT();
+ IS_CHAR('.');
+
+ for (i = 0; i != 6; ++i)
+ {
+ IS_DIGIT();
+ }
+ IS_CHAR(']');
+
+ }
+ else if (g_options.timestamp == EL_TS_SHORT)
+ {
+ IS_CHAR('[');
+ while (*msg != '.' )
+ {
+ IS_DIGIT();
+ }
+
+ ++msg; /* skip the '.' character */
+
+ for (i = 0; i != 6; ++i)
+ {
+ IS_DIGIT();
+ }
+ IS_CHAR(']');
+ }
+ else if (g_options.timestamp == EL_TS_OFF)
+ {
+ /*
+ * we check for nothing here
+ */
+ }
+ else
+ {
+ /*
+ * wrong timestamp option value
+ */
+
+ return -1;
+ }
+
+ /*
+ * check printing file information
+ */
+
+ if (g_options.finfo && expected.file != NULL && expected.line != 0)
+ {
+ char expected_file[FILENAME_MAX + 1];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ IS_CHAR('[');
+ i = 0;
+
+ while (*msg != ':')
+ {
+ tmp[i] = *msg++;
+ if (i++ == EL_FLEN_MAX)
+ {
+ /*
+ * we didn't find ':' character withing maximum lenght
+ * of file - file is too long
+ */
+
+ return -1;
+ }
+ }
+
+ msg++; /* skip ':' character */
+ tmp[i] = '\0';
+ strcpy(expected_file, expected.file);
+
+ if (strcmp(tmp, basename(expected_file)) != 0)
+ {
+ /*
+ * file name in printed log is different than what we set
+ */
+
+ return -1;
+ }
+
+ i = 0;
+
+ while (*msg != ']')
+ {
+ tmp[i] = *msg;
+ if (i++ == EL_PRE_FINFO_LINE_MAX_LEN)
+ {
+ /*
+ * file line lenght is too large, or ending ']' is missing
+ */
+
+ return -1;
+ }
+
+ /*
+ * file line should be a number ;-)
+ */
+
+ IS_DIGIT();
+
+ }
+
+ msg++; /* skip ']' character */
+ tmp[i] = '\0';
+
+ if ((size_t)atoi(tmp) != expected.line)
+ {
+ /*
+ * line number in printed log is different than what was set
+ */
+
+ return -1;
+ }
+ }
+
+ if ((g_options.finfo && expected.file != NULL && expected.line != 0) ||
+ g_options.timestamp != EL_TS_OFF)
+ {
+ /*
+ * file info or timestamp information is enabled, in that case
+ * we check for additional space between info and log message
+ */
+
+ if (*msg++ != ' ')
+ {
+ return -1;
+ }
+ }
+
+ /*
+ * check printing log level
+ */
+
+ if (g_options.print_log_level)
+ {
+ if (*msg++ != levelstr[slevel])
+ {
+ return -1;
+ }
+
+ if (*msg++ != '/')
+ {
+ return -1;
+ }
+ }
+
+ msglen = strlen(expected.msg);
+
+ if (strncmp(msg, expected.msg, msglen) != 0)
+ {
+ return -1;
+ }
+
+ msg += msglen;
+
+ if (g_options.colors)
+ {
+ if (strncmp(msg, color[8], 4) != 0)
+ {
+ /*
+ * expected end of color, got some shit
+ */
+
+ return -1;
+ }
+
+ /*
+ * end of color is always 4 bytes long
+ */
+
+ msg += 4;
+ }
+
+ if (*msg != '\n')
+ {
+ /*
+ * all logs should be ended with new line
+ */
+
+ return -1;
+ }
+
+ /*
+ * set msg to point to next message
+ */
+
+ ++msg;
+ }
+
+ return 0;
+
+#undef IS_CHAR
+#undef IS_DIGIT
+}
+
+
+/* ==========================================================================
+ adds log to array of expected logs and then sends passed log message
+ into el_print
+ ========================================================================== */
+
+
+static void add_log
+(
+ const char *file,
+ size_t line,
+ enum el_level level,
+ const char *msg
+)
+{
+ struct log_message expected;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ expected.file = file;
+ expected.line = line;
+ expected.level = level;
+ expected.msg = msg;
+ rb_write(expected_logs, &expected, 1);
+ el_print(file, line, level, msg);
+}
+
+
+/* ==========================================================================
+ Called before every test, initializes embedlog to known state, and
+ allocates memory for expected_logs buffer
+ ========================================================================== */
+
+
+static void test_prepare(void)
+{
+ el_init();
+ el_option(EL_CUSTOM_PUTS, print_to_buffer);
+ el_option(EL_PRINT_LEVEL, 0);
+ el_option(EL_OUT, EL_OUT_CUSTOM);
+ memset(logbuf, 0, sizeof(logbuf));
+ expected_logs = rb_new(1024, sizeof(struct log_message),
+ O_NONTHREAD | O_NONBLOCK);
+}
+
+
+/* ==========================================================================
+ Called after every test. Frees all memory allocated by test_prepare
+ ========================================================================== */
+
+
+static void test_cleanup(void)
+{
+ el_cleanup();
+ rb_destroy(expected_logs);
+}
+
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ _____
+ / __// _ \ / ___// __// ___/
+ / /_ / __/(__ )/ /_ (__ )
+ \__/ \___//____/ \__//____/
+
+ ========================================================================== */
+
+
+static void print_simple_message(void)
+{
+ add_log(ELF, "print_simple_message");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_simple_multiple_message(void)
+{
+ add_log(ELF, "print_simple_multiple_message first");
+ add_log(ELF, "print_simple_multiple_message second");
+ add_log(ELF, "print_simple_multiple_message third");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_log_level(void)
+{
+ el_option(EL_PRINT_LEVEL, 1);
+ el_option(EL_LEVEL, EL_DBG);
+ add_log(ELF, "print_log_level fatal message");
+ add_log(ELA, "print_log_level alert message");
+ add_log(ELC, "print_log_level critical message");
+ add_log(ELE, "print_log_level error message");
+ add_log(ELW, "print_log_level warning message");
+ add_log(ELN, "print_log_level notice message");
+ add_log(ELI, "print_log_level info message");
+ add_log(ELD, "print_log_level debug message");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_colorful_output(void)
+{
+ el_option(EL_COLORS, 1);
+ el_option(EL_LEVEL, EL_DBG + 2);
+ add_log(ELF, "print_colorful_output fatal message");
+ add_log(ELA, "print_colorful_output alert message");
+ add_log(ELC, "print_colorful_output critical message");
+ add_log(ELE, "print_colorful_output error message");
+ add_log(ELW, "print_colorful_output warning message");
+ add_log(ELN, "print_colorful_output notice message");
+ add_log(ELI, "print_colorful_output info message");
+ add_log(ELD, "print_colorful_output debug message");
+ add_log(ELD + 1, "print_colorful_output debug + 1 message");
+ add_log(ELD + 2, "print_colorful_output debug + 2 message");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_custom_log_level(void)
+{
+ el_option(EL_PRINT_LEVEL, 1);
+ el_option(EL_LEVEL, EL_DBG + 5);
+ add_log(ELD + 4, "print_custom_log_level custom debug 4");
+ add_log(ELD + 5, "print_custom_log_level custom debug 5");
+ add_log(ELD + 6, "print_custom_log_level custom debug 6");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_timestamp_short(void)
+{
+ el_option(EL_TS, EL_TS_SHORT);
+ add_log(ELF, "print_timestamp_short first");
+ add_log(ELF, "print_timestamp_short second");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_timestamp_long(void)
+{
+ el_option(EL_TS, EL_TS_LONG);
+ add_log(ELF, "print_timestamp_long first");
+ add_log(ELF, "print_timestamp_long second");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_finfo(void)
+{
+ el_option(EL_FINFO, 1);
+ add_log(ELF, "print_finfo first");
+ add_log(ELF, "print_finfo second");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_different_clocks(void)
+{
+ int i;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ for (i = EL_TS_TM_CLOCK; i != EL_TS_TM_ERROR; ++i)
+ {
+ test_prepare();
+ el_option(EL_TS_TM, i);
+ el_option(EL_TS, EL_TS_LONG);
+ add_log(ELI, "clock test");
+ mt_fok(print_check());
+ test_cleanup();
+ }
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_mix_of_everything(void)
+{
+ int level;
+ int timestamp;
+ int printlevel;
+ int finfo;
+ int colors;
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ for (level = EL_FATAL; level <= EL_DBG; ++level)
+ for (timestamp = EL_TS_OFF; timestamp != EL_TS_ERROR; ++timestamp)
+ for (printlevel = 0; printlevel <= 1; ++printlevel)
+ for (finfo = 0; finfo <= 1; ++finfo)
+ for (colors = 0; colors <= 1; ++colors)
+ {
+ test_prepare();
+ el_option(EL_LEVEL, level);
+ el_option(EL_TS, timestamp);
+ el_option(EL_PRINT_LEVEL, printlevel);
+ el_option(EL_FINFO, finfo);
+ el_option(EL_COLORS, colors);
+
+ add_log(ELF, "fatal message");
+ add_log(ELA, "alert message");
+ add_log(ELC, "critical message");
+ add_log(ELE, "error message");
+ add_log(ELW, "warning message");
+ add_log(ELN, "notice message");
+ add_log(ELI, "info message");
+ add_log(ELD, "debug message");
+ mt_fok(print_check());
+
+ test_cleanup();
+ }
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_too_long_print_truncate(void)
+{
+ char msg[EL_LOG_MAX + 3];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ memset(msg, 'a', sizeof(msg));
+ msg[sizeof(msg) - 1] = '\0';
+ msg[sizeof(msg) - 2] = '3';
+ msg[sizeof(msg) - 3] = '2';
+ msg[sizeof(msg) - 4] = '1';
+ msg[sizeof(msg) - 4] = '0';
+
+ add_log(ELI, "not truncated");
+ add_log(ELI, msg);
+
+ /*
+ * while el_print will make copy of msg, our test print_check function
+ * will just use pointer to our msg here, and since we expect message to
+ * be truncated, we truncate it here and print_check will take this
+ * truncated message as expected one.
+ */
+
+ msg[sizeof(msg) - 3] = '\0';
+
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_truncate_with_date(void)
+{
+ char msg[EL_LOG_MAX + 3];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_option(EL_TS, EL_TS_LONG);
+ memset(msg, 'a', sizeof(msg));
+ msg[sizeof(msg) - 1] = '\0';
+ msg[sizeof(msg) - 2] = '3';
+ msg[sizeof(msg) - 3] = '2';
+ msg[sizeof(msg) - 4] = '1';
+ msg[sizeof(msg) - 4] = '0';
+
+ add_log(ELI, "not truncated");
+ add_log(ELI, msg);
+
+ msg[sizeof(msg) - 3] = '\0';
+
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_truncate_with_all_options(void)
+{
+ char msg[EL_LOG_MAX + 3];
+ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
+
+
+ el_option(EL_TS, EL_TS_LONG);
+ el_option(EL_FINFO, 1);
+ el_option(EL_PRINT_LEVEL, 1);
+ memset(msg, 'a', sizeof(msg));
+ msg[sizeof(msg) - 1] = '\0';
+ msg[sizeof(msg) - 2] = '3';
+ msg[sizeof(msg) - 3] = '2';
+ msg[sizeof(msg) - 4] = '1';
+ msg[sizeof(msg) - 4] = '0';
+
+ add_log(ELI, "not truncated");
+ add_log(ELI, msg);
+
+ msg[sizeof(msg) - 3] = '\0';
+
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_with_no_output_available(void)
+{
+ el_option(EL_OUT, EL_OUT_NONE);
+ mt_ferr(el_print(ELI, "i'll be back"), ENODEV);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_level_not_high_enough(void)
+{
+ mt_ferr(el_print(ELD, "i won't be printed"), ERANGE);
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_finfo_path(void)
+{
+ el_option(EL_FINFO, 1);
+ add_log("source/code/file.c", 10, EL_ALERT, "some message");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_nofinfo(void)
+{
+ el_option(EL_FINFO, 1);
+ add_log(NULL, 0, EL_ALERT, "no file info");
+ mt_fok(print_check());
+}
+
+
+/* ==========================================================================
+ ========================================================================== */
+
+
+static void print_null(void)
+{
+ mt_ferr(el_print(ELA, NULL), EINVAL);
+}
+
+/* ==========================================================================
+ __ __
+ / /_ ___ _____ / /_ ____ _ _____ ____ __ __ ____
+ / __// _ \ / ___// __/ / __ `// ___// __ \ / / / // __ \
+ / /_ / __/(__ )/ /_ / /_/ // / / /_/ // /_/ // /_/ /
+ \__/ \___//____/ \__/ \__, //_/ \____/ \__,_// .___/
+ /____/ /_/
+ ========================================================================== */
+
+
+void el_print_test_group(void)
+{
+ mt_run(print_different_clocks);
+ mt_run(print_mix_of_everything);
+
+ mt_prepare_test = &test_prepare;
+ mt_cleanup_test = &test_cleanup;
+
+ mt_run(print_simple_message);
+ mt_run(print_simple_multiple_message);
+ mt_run(print_log_level);
+ mt_run(print_colorful_output);
+ mt_run(print_custom_log_level);
+ mt_run(print_timestamp_short);
+ mt_run(print_timestamp_long);
+ mt_run(print_finfo);
+ mt_run(print_too_long_print_truncate);
+ mt_run(print_truncate_with_date);
+ mt_run(print_truncate_with_all_options);
+ mt_run(print_with_no_output_available);
+ mt_run(print_level_not_high_enough);
+ mt_run(print_finfo_path);
+ mt_run(print_nofinfo);
+ mt_run(print_null);
+}