aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Łyszczek <michal.lyszczek@bofc.pl>2019-05-15 19:57:55 +0200
committerMichał Łyszczek <michal.lyszczek@bofc.pl>2019-05-15 19:57:55 +0200
commit37983a109814d4f8d2412fcbdb77908051909ab4 (patch)
treea8eecbfdd8cb79037c4cab90e5ed8d29ee67c78f
parentf7f2eaa207d5cf79fc834881ce7e8ba23e24227d (diff)
downloadembedlog-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.ac23
-rw-r--r--include/Makefile.am3
-rw-r--r--include/embedlog.h.in29
-rw-r--r--src/el-options.c14
-rw-r--r--tst/test-el-options.c42
-rw-r--r--tst/test-el-print.c2
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);