summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/libcsupport/Makefile.am1
-rw-r--r--cpukit/libcsupport/include/rtems/assoc.h33
-rw-r--r--cpukit/libcsupport/src/assoc32tostring.c61
-rw-r--r--testsuites/sptests/spassoc01/init.c61
4 files changed, 155 insertions, 1 deletions
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 559ad81446..ec5dd02832 100644
--- a/cpukit/libcsupport/Makefile.am
+++ b/cpukit/libcsupport/Makefile.am
@@ -38,6 +38,7 @@ ASSOCIATION_C_FILES = src/assoclocalbyname.c \
src/assocnamebyremote.c src/assocptrbylocal.c src/assocptrbyname.c \
src/assocptrbyremote.c src/assocremotebylocalbitfield.c \
src/assocremotebylocal.c src/assocremotebyname.c
+ASSOCIATION_C_FILES += src/assoc32tostring.c
BASE_FS_C_FILES = src/base_fs.c src/mount.c src/unmount.c src/libio.c \
src/mount-mgr.c src/mount-mktgt.c src/libio_init.c \
diff --git a/cpukit/libcsupport/include/rtems/assoc.h b/cpukit/libcsupport/include/rtems/assoc.h
index c4933159e0..9f65ba60a4 100644
--- a/cpukit/libcsupport/include/rtems/assoc.h
+++ b/cpukit/libcsupport/include/rtems/assoc.h
@@ -16,7 +16,8 @@
*/
/**@{*/
-#include <stdint.h> /* uint32_t */
+#include <stddef.h>
+#include <stdint.h>
#ifdef __cplusplus
extern "C" {
@@ -150,6 +151,36 @@ const char *rtems_assoc_name_bad(
);
#endif
+typedef struct {
+ uint32_t bits;
+ const char *name;
+} rtems_assoc_32_pair;
+
+/**
+ * @brief Converts the specified value into a text representation.
+ *
+ * @param[in] value The value to convert.
+ * @param[in] buffer The buffer for the text representation.
+ * @param[in] buffer_size The buffer size in characters.
+ * @param[in] pairs Names for particular bits.
+ * @param[in] pair_count Count of pairs.
+ * @param[in] separator Separator between individual names.
+ * @param[in] fallback Fallback value in case no bits contained in the pairs
+ * are set in the value.
+ *
+ * @retval The length of the text representation. May be greater than the
+ * buffer size if truncation occurred.
+ */
+size_t rtems_assoc_32_to_string(
+ uint32_t value,
+ char *buffer,
+ size_t buffer_size,
+ const rtems_assoc_32_pair *pairs,
+ size_t pair_count,
+ const char *separator,
+ const char *fallback
+);
+
#ifdef __cplusplus
}
#endif
diff --git a/cpukit/libcsupport/src/assoc32tostring.c b/cpukit/libcsupport/src/assoc32tostring.c
new file mode 100644
index 0000000000..31b08857d3
--- /dev/null
+++ b/cpukit/libcsupport/src/assoc32tostring.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/assoc.h>
+
+#include <stdbool.h>
+#include <string.h>
+
+static size_t space( size_t buffer_size, size_t len )
+{
+ if ( len < buffer_size ) {
+ return buffer_size - len;
+ } else {
+ return 0;
+ }
+}
+
+size_t rtems_assoc_32_to_string(
+ uint32_t value,
+ char *buffer,
+ size_t buffer_size,
+ const rtems_assoc_32_pair *pairs,
+ size_t pair_count,
+ const char *separator,
+ const char *fallback
+)
+{
+ size_t len;
+ size_t i;
+
+ len = 0;
+
+ for ( i = 0; i < pair_count ; ++i ) {
+ const rtems_assoc_32_pair *p;
+
+ p = &pairs[ i ];
+
+ if ( ( value & p->bits ) != 0 ) {
+ if ( len > 0 ) {
+ len += strlcpy( &buffer[ len ], separator, space( buffer_size, len ) );
+ }
+
+ len += strlcpy( &buffer[ len ], p->name, space( buffer_size, len ) );
+ }
+ }
+
+ if ( len == 0 ) {
+ len += strlcpy( buffer, fallback, buffer_size );
+ }
+
+ return len;
+}
diff --git a/testsuites/sptests/spassoc01/init.c b/testsuites/sptests/spassoc01/init.c
index 2cd14f9297..ba3873ac0e 100644
--- a/testsuites/sptests/spassoc01/init.c
+++ b/testsuites/sptests/spassoc01/init.c
@@ -61,6 +61,65 @@ static void reset_name( void )
memset( name, 0, 40 );
}
+static void test_assoc_32_to_string( void )
+{
+ static const rtems_assoc_32_pair pairs[] = {
+ { 1, "A" },
+ { 2, "LOOOOONG" },
+ { 4, "C" }
+ };
+ char buf[4];
+ size_t len;
+
+ len = rtems_assoc_32_to_string(
+ 0,
+ buf,
+ sizeof( buf ),
+ pairs,
+ RTEMS_ARRAY_SIZE( pairs ),
+ ":",
+ "D"
+ );
+ rtems_test_assert( len == 1 );
+ rtems_test_assert( strcmp( buf, "D" ) == 0 );
+
+ len = rtems_assoc_32_to_string(
+ 1,
+ buf,
+ sizeof( buf ),
+ pairs,
+ RTEMS_ARRAY_SIZE( pairs ),
+ ":",
+ "D"
+ );
+ rtems_test_assert( len == 1 );
+ rtems_test_assert( strcmp( buf, "A" ) == 0 );
+
+ len = rtems_assoc_32_to_string(
+ 5,
+ buf,
+ sizeof( buf ),
+ pairs,
+ RTEMS_ARRAY_SIZE( pairs ),
+ ":",
+ "D"
+ );
+ rtems_test_assert( len == 3 );
+ rtems_test_assert( strcmp( buf, "A:C" ) == 0 );
+
+ len = rtems_assoc_32_to_string(
+ 7,
+ buf,
+ sizeof( buf ),
+ pairs,
+ RTEMS_ARRAY_SIZE( pairs ),
+ ":",
+ "D"
+ );
+ rtems_test_assert( len == 12 );
+ rtems_test_assert( strcmp( buf, "A:L" ) == 0 );
+}
+
rtems_task Init(
rtems_task_argument argument
)
@@ -217,6 +276,8 @@ rtems_task Init(
free( name );
+ test_assoc_32_to_string();
+
TEST_END();
rtems_test_exit(0);