diff options
author | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2019-05-15 19:57:55 +0200 |
---|---|---|
committer | Michał Łyszczek <michal.lyszczek@bofc.pl> | 2019-05-15 19:57:55 +0200 |
commit | 37983a109814d4f8d2412fcbdb77908051909ab4 (patch) | |
tree | a8eecbfdd8cb79037c4cab90e5ed8d29ee67c78f | |
parent | f7f2eaa207d5cf79fc834881ce7e8ba23e24227d (diff) | |
download | embedlog-37983a109814d4f8d2412fcbdb77908051909ab4.tar.gz embedlog-37983a109814d4f8d2412fcbdb77908051909ab4.tar.bz2 embedlog-37983a109814d4f8d2412fcbdb77908051909ab4.zip |
Conditionally remove fields from "struct el" to save space
Now that we have to modify "struct el" without breaking ABI,
we can make there some changes.
To save memory when some options are not used, we now disable
some fields in "struct el". This change is safe when users are
using stable ABI approach.
Signed-off-by: Michał Łyszczek <michal.lyszczek@bofc.pl>
-rw-r--r-- | configure.ac | 23 | ||||
-rw-r--r-- | include/Makefile.am | 3 | ||||
-rw-r--r-- | include/embedlog.h.in | 29 | ||||
-rw-r--r-- | src/el-options.c | 14 | ||||
-rw-r--r-- | tst/test-el-options.c | 42 | ||||
-rw-r--r-- | tst/test-el-print.c | 2 |
6 files changed, 89 insertions, 24 deletions
diff --git a/configure.ac b/configure.ac index b6e35b5..40f0ecd 100644 --- a/configure.ac +++ b/configure.ac @@ -6,17 +6,9 @@ AC_PROG_CC_C89 AC_CANONICAL_HOST AC_PROG_LIBTOOL AC_CONFIG_MACRO_DIR([m4]) -AC_CONFIG_FILES([Makefile \ - src/Makefile \ - include/Makefile \ - tst/Makefile \ - man/Makefile \ - examples/Makefile \ - www/Makefile]) AC_CONFIG_SRCDIR([configure.ac]) AC_CONFIG_HEADERS([config.h]) - AC_SEARCH_LIBS([pow], [m]) ### @@ -64,6 +56,7 @@ AC_SUBST(COVERAGE_CFLAGS) AC_SUBST(COVERAGE_CXXFLAGS) AC_SUBST(COVERAGE_LDFLAGS) +AC_CONFIG_FILES(include/embedlog.h) ### # --enable-feature options @@ -96,14 +89,17 @@ AC_ARG_ENABLE([out-file], [], [enable_out_file="yes"]) AM_CONDITIONAL([ENABLE_OUT_FILE], [test "x$enable_out_file" = "xyes"]) +ENABLE_OUT_FILE=0 AS_IF([test "x$enable_out_file" = "xyes"], [ AC_DEFINE([ENABLE_OUT_FILE], [1], [Enable printing to file]) + ENABLE_OUT_FILE=1 AC_CHECK_FUNCS(access stat fsync fileno) AC_CHECK_FUNCS([fopen fclose fwrite remove rename],, AC_MSG_ERROR(not found, needed by --enable-out-file)) ]) +AC_SUBST(ENABLE_OUT_FILE) ### # --enable-out-tty @@ -115,14 +111,17 @@ AC_ARG_ENABLE([out-tty], [], [enable_out_tty="yes"]) AM_CONDITIONAL([ENABLE_OUT_TTY], [test "x$enable_out_tty" = "xyes"]) +ENABLE_OUT_TTY=0 AS_IF([test "x$enable_out_tty" = "xyes"], [ AC_DEFINE([ENABLE_OUT_TTY], [1], [Enable printing to tty]) + ENABLE_OUT_TTY=1 AC_CHECK_HEADERS(termios.h) AC_CHECK_FUNCS([open tcgetattr cfsetispeed tcsetattr close],, AC_MSG_ERROR(not found, needed by --enable-out-tty)) ]) +AC_SUBST(ENABLE_OUT_TTY) ### # --enable-out-custom @@ -133,14 +132,17 @@ AC_ARG_ENABLE([out-custom], AS_HELP_STRING([--enable-out-custom], [Enable printing to custom]), [], [enable_out_custom="yes"]) +ENABLE_OUT_CUSTOM=0 AM_CONDITIONAL([ENABLE_OUT_CUSTOM], [test "x$enable_out_custom" = "xyes"]) AS_IF([test "x$enable_out_custom" = "xyes"], [ AC_DEFINE([ENABLE_OUT_CUSTOM], [1], [Enable printing to custom]) + ENABLE_OUT_CUSTOM=1 AC_CHECK_FUNCS([fopen fclose fwrite remove rename],, AC_MSG_ERROR(not found, needed by --enable-out-custom)) ]) +AC_SUBST(ENABLE_OUT_CUSTOM) ### # --enable-timestamp @@ -293,13 +295,16 @@ AC_ARG_ENABLE([prefix], AS_HELP_STRING([--enable-prefix], [Enable printing prefix to each message]), [], [enable_prefix="yes"]) +ENABLE_PREFIX=0 AS_IF([test "x$enable_prefix" = "xyes"], [ AC_DEFINE([ENABLE_PREFIX], [1], [Enable printing prefix to each message]) + ENABLE_PREFIX=1 AC_CHECK_FUNCS([strncat strlen],, AC_MSG_ERROR(not found, needed by --enable-prefix)) ]) +AC_SUBST(ENABLE_PREFIX) ### # --enable-finfo @@ -467,6 +472,8 @@ AC_ARG_ENABLE([analyzer], [enable_analyzer="yes"], [enable_analyzer="no"]) AM_CONDITIONAL([ENABLE_ANALYZER], [test "x$enable_analyzer" = "xyes"]) +AC_CONFIG_FILES([Makefile src/Makefile include/Makefile tst/Makefile \ + man/Makefile examples/Makefile www/Makefile]) AC_OUTPUT diff --git a/include/Makefile.am b/include/Makefile.am index 8a1b55a..250916f 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,4 +1 @@ include_HEADERS = embedlog.h - -embedlog.h: - cp embedlog.h.in $@ diff --git a/include/embedlog.h.in b/include/embedlog.h.in index a3deeb1..021ae7d 100644 --- a/include/embedlog.h.in +++ b/include/embedlog.h.in @@ -170,6 +170,20 @@ enum el_option_timestamp_fractions typedef int (*el_custom_puts)(const char *s, void *user); +/* Main embedlog object that holds printing options and other data. + * This definition is here so people that don't care about stable + * ABI can avoid mallocs and allocate objects on stack. Check + * el_overview(7) for more information about this. + * + * Any #if [0,1] in this struct is generated during compilation and + * should no be changed without library recompilation, unless you + * like when your program executes undefined behaviour. + * + * It's generated as #if [0,1] so this is applied system-wide, if + * it were to be defined like #if ENABLE_OUT_FILE, then every + * compilation unit that uses embedlog would have to define that to + * either 1 or 0. Easy for mistakes and hard to find bugs. + */ struct el { unsigned int outputs:7; @@ -183,9 +197,9 @@ struct el unsigned int funcinfo:1; unsigned int level:3; unsigned int level_current_msg:3; - unsigned int file_sync_level:3; - int serial_fd; +#if @ENABLE_OUT_FILE@ + unsigned int file_sync_level:3; unsigned int frotate_number; unsigned int fcurrent_rotate; unsigned long frotate_size; @@ -195,9 +209,20 @@ struct el FILE *file; char *current_log; const char *fname; +#endif + +#if @ENABLE_OUT_TTY@ + int serial_fd; +#endif + +#if @ENABLE_PREFIX@ const char *prefix; +#endif + +#if @ENABLE_OUT_CUSTOM@ el_custom_puts custom_puts; void *custom_puts_user; +#endif }; int el_init(void); diff --git a/src/el-options.c b/src/el-options.c index 67d9548..3401c11 100644 --- a/src/el-options.c +++ b/src/el-options.c @@ -158,12 +158,18 @@ static int el_vooption el->level = value_int; return 0; + +# if ENABLE_OUT_FILE + case EL_FSYNC_LEVEL: value_int = va_arg(ap, int); VALID(EINVAL, value_int <= 7); el->file_sync_level = value_int; return 0; +# endif /* ENABLE_OUT_FILE */ + + case EL_OUT: value_int = va_arg(ap, int); value_int = value_int == EL_OUT_ALL ? VALID_OUTS : value_int; @@ -428,9 +434,15 @@ int el_oinit el->print_newline = 1; el->level = EL_INFO; el->level_current_msg = EL_DBG; - el->file_sync_level = EL_FATAL; + +#if ENABLE_OUT_TTY el->serial_fd = -1; +#endif + +#if ENABLE_OUT_FILE el->file_sync_every = 32768; + el->file_sync_level = EL_FATAL; +#endif return 0; } diff --git a/tst/test-el-options.c b/tst/test-el-options.c index 09ad7a1..bdcbade 100644 --- a/tst/test-el-options.c +++ b/tst/test-el-options.c @@ -95,7 +95,6 @@ static void options_init(void) memset(&default_el, 0, sizeof(default_el)); default_el.outputs = EL_OUT_STDERR; default_el.level = EL_INFO; - default_el.file_sync_level = EL_FATAL; default_el.level_current_msg = EL_DBG; default_el.colors = 0; default_el.timestamp = EL_TS_OFF; @@ -103,9 +102,9 @@ static void options_init(void) default_el.timestamp_fractions = EL_TS_FRACT_OFF; default_el.print_log_level = 1; default_el.print_newline = 1; - default_el.custom_puts = NULL; - default_el.serial_fd = -1; +#if ENABLE_OUT_FILE + default_el.file_sync_level = EL_FATAL; default_el.funcinfo = 0; default_el.finfo = 0; default_el.frotate_number = 0; @@ -115,6 +114,15 @@ static void options_init(void) default_el.file = NULL; default_el.file_sync_every = 32768; default_el.fname = NULL; +#endif + +#if ENABLE_OUT_TTY + default_el.serial_fd = -1; +#endif + +#if ENABLE_OUT_CUSTOM + default_el.custom_puts = NULL; +#endif mt_fail(el_oinit(&el) == 0); mt_fail(memcmp(&el, &default_el, sizeof(el)) == 0); @@ -180,6 +188,7 @@ static void options_file_sync_level_set(void) for (i = 0; i != 16; ++i) { +#if ENABLE_OUT_FILE if (i <= EL_DBG) { mt_fail(el_option(EL_FSYNC_LEVEL, i) == 0); @@ -190,6 +199,9 @@ static void options_file_sync_level_set(void) mt_ferr(el_option(EL_FSYNC_LEVEL, i), EINVAL); mt_fail(g_el.file_sync_level == EL_DBG); } +#else + mt_ferr(el_option(EL_FSYNC_LEVEL, i), ENOSYS); +#endif } } @@ -480,15 +492,16 @@ static void options_ooption_test(void) static void options_prefix(void) { - el_option(EL_PREFIX, "prefix"); #if ENABLE_PREFIX + mt_fok(el_option(EL_PREFIX, "prefix")); mt_fok(strcmp("prefix", g_el.prefix)); -#else + mt_fok(el_option(EL_PREFIX, NULL)); mt_fail(g_el.prefix == NULL); +#else + mt_ferr(el_option(EL_PREFIX, "prefix"), ENOSYS); + mt_ferr(el_option(EL_PREFIX, NULL), ENOSYS); #endif - el_option(EL_PREFIX, NULL); - mt_fail(g_el.prefix == NULL); } @@ -516,7 +529,6 @@ static void options_global_el_after_el_cleanup(void) memset(&default_el, 0, sizeof(default_el)); default_el.outputs = EL_OUT_STDERR; default_el.level = EL_INFO; - default_el.file_sync_level = EL_FATAL; default_el.level_current_msg = EL_DBG; default_el.colors = 0; default_el.timestamp = EL_TS_OFF; @@ -524,9 +536,9 @@ static void options_global_el_after_el_cleanup(void) default_el.timestamp_fractions = EL_TS_FRACT_OFF; default_el.print_log_level = 1; default_el.print_newline = 1; - default_el.custom_puts = NULL; - default_el.serial_fd = -1; +#if ENABLE_OUT_FILE + default_el.file_sync_level = EL_FATAL; default_el.funcinfo = 0; default_el.finfo = 0; default_el.frotate_number = 0; @@ -536,6 +548,16 @@ static void options_global_el_after_el_cleanup(void) default_el.file = NULL; default_el.file_sync_every = 32768; default_el.fname = NULL; +#endif + +#if ENABLE_OUT_TTY + default_el.serial_fd = -1; +#endif + +#if ENABLE_OUT_CUSTOM + default_el.custom_puts = NULL; +#endif + el_init(); diff --git a/tst/test-el-print.c b/tst/test-el-print.c index 1cf64c0..1d8851a 100644 --- a/tst/test-el-print.c +++ b/tst/test-el-print.c @@ -445,6 +445,7 @@ static int print_check(void) * check for prefix */ +#if ENABLE_PREFIX if (g_el.prefix) { char expected_prefix[EL_PREFIX_LEN + 1] = {0}; @@ -461,6 +462,7 @@ static int print_check(void) msg += expected_prefix_len; } +#endif msglen = strlen(expected.msg); |