2011-12-22 15:19:25 +00:00
|
|
|
/*
|
2015-03-20 16:50:41 +00:00
|
|
|
* \brief String utilities
|
2011-12-22 15:19:25 +00:00
|
|
|
* \author Norman Feske
|
2012-08-02 14:39:16 +00:00
|
|
|
* \author Sebastian Sumpf
|
2011-12-22 15:19:25 +00:00
|
|
|
* \date 2006-05-10
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2017-02-20 12:23:52 +00:00
|
|
|
* Copyright (C) 2006-2017 Genode Labs GmbH
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* This file is part of the Genode OS framework, which is distributed
|
2017-02-20 12:23:52 +00:00
|
|
|
* under the terms of the GNU Affero General Public License version 3.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _INCLUDE__UTIL__STRING_H_
|
|
|
|
#define _INCLUDE__UTIL__STRING_H_
|
|
|
|
|
|
|
|
#include <base/stdint.h>
|
2016-07-13 13:15:03 +00:00
|
|
|
#include <base/output.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
#include <util/misc_math.h>
|
2012-08-02 14:39:16 +00:00
|
|
|
#include <cpu/string.h>
|
2011-12-22 15:19:25 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
namespace Genode {
|
|
|
|
|
|
|
|
class Number_of_bytes;
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
class Cstring;
|
2015-03-04 20:12:14 +00:00
|
|
|
template <Genode::size_t> class String;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-04-10 15:45:35 +00:00
|
|
|
* Wrapper of 'size_t' for selecting the 'ascii_to' function to parse byte values
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
|
|
|
class Genode::Number_of_bytes
|
|
|
|
{
|
|
|
|
size_t _n;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Default constructor
|
|
|
|
*/
|
|
|
|
Number_of_bytes() : _n(0) { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor, to be used implicitly via assignment operator
|
|
|
|
*/
|
|
|
|
Number_of_bytes(size_t n) : _n(n) { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert number of bytes to 'size_t' value
|
|
|
|
*/
|
|
|
|
operator size_t() const { return _n; }
|
2017-02-16 16:24:44 +00:00
|
|
|
|
|
|
|
void print(Output &output) const
|
|
|
|
{
|
|
|
|
using Genode::print;
|
|
|
|
|
|
|
|
enum { KB = 1024UL, MB = KB*1024UL, GB = MB*1024UL };
|
|
|
|
|
2017-03-16 11:42:44 +00:00
|
|
|
if (_n == 0) print(output, 0);
|
|
|
|
else if (_n % GB == 0) print(output, _n/GB, "G");
|
2017-02-16 16:24:44 +00:00
|
|
|
else if (_n % MB == 0) print(output, _n/MB, "M");
|
|
|
|
else if (_n % KB == 0) print(output, _n/KB, "K");
|
|
|
|
else print(output, _n);
|
|
|
|
}
|
2015-03-04 20:12:14 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/***********************
|
|
|
|
** Utility functions **
|
|
|
|
***********************/
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
namespace Genode {
|
|
|
|
|
|
|
|
/**
|
2015-03-20 16:50:41 +00:00
|
|
|
* Return length of null-terminated string in bytes
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
inline size_t strlen(const char *s)
|
|
|
|
{
|
|
|
|
size_t res = 0;
|
|
|
|
for (; s && *s; s++, res++);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compare two strings
|
|
|
|
*
|
|
|
|
* \param len maximum number of characters to compare,
|
|
|
|
* default is unlimited
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* \return 0 if both strings are equal, or
|
|
|
|
* a positive number if s1 is higher than s2, or
|
|
|
|
* a negative number if s1 is lower than s2
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
inline int strcmp(const char *s1, const char *s2, size_t len = ~0UL)
|
|
|
|
{
|
|
|
|
for (; *s1 && *s1 == *s2 && len; s1++, s2++, len--) ;
|
|
|
|
return len ? *s1 - *s2 : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2013-01-10 14:43:55 +00:00
|
|
|
/**
|
2015-03-20 16:50:41 +00:00
|
|
|
* Copy memory buffer to a potentially overlapping destination buffer
|
2013-01-10 14:43:55 +00:00
|
|
|
*
|
|
|
|
* \param dst destination memory block
|
|
|
|
* \param src source memory block
|
|
|
|
* \param size number of bytes to move
|
|
|
|
*
|
|
|
|
* \return pointer to destination memory block
|
|
|
|
*/
|
|
|
|
inline void *memmove(void *dst, const void *src, size_t size)
|
|
|
|
{
|
|
|
|
char *d = (char *)dst, *s = (char *)src;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (s > d)
|
|
|
|
for (i = 0; i < size; i++, *d++ = *s++);
|
|
|
|
else
|
|
|
|
for (s += size - 1, d += size - 1, i = size; i-- > 0; *d-- = *s--);
|
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/**
|
2015-03-20 16:50:41 +00:00
|
|
|
* Copy memory buffer to a non-overlapping destination buffer
|
2011-12-22 15:19:25 +00:00
|
|
|
*
|
|
|
|
* \param dst destination memory block
|
|
|
|
* \param src source memory block
|
|
|
|
* \param size number of bytes to copy
|
|
|
|
*
|
|
|
|
* \return pointer to destination memory block
|
|
|
|
*/
|
|
|
|
inline void *memcpy(void *dst, const void *src, size_t size)
|
|
|
|
{
|
|
|
|
char *d = (char *)dst, *s = (char *)src;
|
|
|
|
size_t i;
|
|
|
|
|
2013-01-10 14:43:55 +00:00
|
|
|
/* check for overlap */
|
|
|
|
if ((d + size > s) && (s + size > d))
|
|
|
|
return memmove(dst, src, size);
|
|
|
|
|
2012-08-02 14:39:16 +00:00
|
|
|
/* try cpu specific version first */
|
|
|
|
if ((i = size - memcpy_cpu(dst, src, size)) == size)
|
|
|
|
return dst;
|
|
|
|
|
|
|
|
d += i; s += i; size -= i;
|
|
|
|
|
|
|
|
/* copy eight byte chunks */
|
|
|
|
for (i = size >> 3; i > 0; i--, *d++ = *s++,
|
|
|
|
*d++ = *s++,
|
|
|
|
*d++ = *s++,
|
|
|
|
*d++ = *s++,
|
|
|
|
*d++ = *s++,
|
|
|
|
*d++ = *s++,
|
|
|
|
*d++ = *s++,
|
|
|
|
*d++ = *s++);
|
|
|
|
|
|
|
|
/* copy left over */
|
|
|
|
for (i = 0; i < (size & 0x7); i++, *d++ = *s++);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Copy string
|
|
|
|
*
|
|
|
|
* \param dst destination buffer
|
|
|
|
* \param src buffer holding the null-terminated source string
|
|
|
|
* \param size maximum number of characters to copy
|
|
|
|
* \return pointer to destination string
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* Note that this function is not fully compatible to the C standard, in
|
|
|
|
* particular there is no zero-padding if the length of 'src' is smaller
|
|
|
|
* than 'size'. Furthermore, in contrast to the libc version, this function
|
|
|
|
* always produces a null-terminated string in the 'dst' buffer if the
|
|
|
|
* 'size' argument is greater than 0.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
inline char *strncpy(char *dst, const char *src, size_t size)
|
|
|
|
{
|
|
|
|
/* sanity check for corner case of a zero-size destination buffer */
|
|
|
|
if (size == 0) return dst;
|
|
|
|
|
|
|
|
/* backup original 'dst' for the use as return value */
|
|
|
|
char *orig_dst = dst;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Copy characters from 'src' to 'dst' respecting the 'size' limit.
|
|
|
|
* In each iteration, the 'size' variable holds the maximum remaining
|
|
|
|
* size. We have to leave at least one character free to add the null
|
|
|
|
* termination afterwards.
|
|
|
|
*/
|
|
|
|
while ((size-- > 1UL) && *src)
|
|
|
|
*dst++ = *src++;
|
|
|
|
|
|
|
|
/* append null termination to the destination buffer */
|
|
|
|
*dst = 0;
|
|
|
|
|
|
|
|
return orig_dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compare memory blocks
|
|
|
|
*
|
2015-03-20 16:50:41 +00:00
|
|
|
* \return 0 if both memory blocks are equal, or
|
|
|
|
* a negative number if 'p0' is less than 'p1', or
|
|
|
|
* a positive number if 'p0' is greater than 'p1'
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
inline int memcmp(const void *p0, const void *p1, size_t size)
|
|
|
|
{
|
2013-01-22 09:51:32 +00:00
|
|
|
const unsigned char *c0 = (const unsigned char *)p0;
|
|
|
|
const unsigned char *c1 = (const unsigned char *)p1;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
size_t i;
|
|
|
|
for (i = 0; i < size; i++)
|
2013-01-22 09:51:32 +00:00
|
|
|
if (c0[i] != c1[i]) return c0[i] - c1[i];
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2015-03-20 16:50:41 +00:00
|
|
|
* Fill destination buffer with given value
|
|
|
|
*
|
|
|
|
* \param dst destination buffer
|
|
|
|
* \param i byte value
|
|
|
|
* \param size buffer size in bytes
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
|
|
|
inline void *memset(void *dst, int i, size_t size)
|
|
|
|
{
|
|
|
|
while (size--) ((char *)dst)[size] = i;
|
|
|
|
return dst;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert ASCII character to digit
|
|
|
|
*
|
|
|
|
* \param hex consider hexadecimals
|
|
|
|
* \return digit or -1 on error
|
|
|
|
*/
|
|
|
|
inline int digit(char c, bool hex = false)
|
|
|
|
{
|
|
|
|
if (c >= '0' && c <= '9') return c - '0';
|
|
|
|
if (hex && c >= 'a' && c <= 'f') return c - 'a' + 10;
|
|
|
|
if (hex && c >= 'A' && c <= 'F') return c - 'A' + 10;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if character is a letter
|
|
|
|
*/
|
|
|
|
inline bool is_letter(char c)
|
|
|
|
{
|
|
|
|
return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if character is a digit
|
|
|
|
*/
|
|
|
|
inline bool is_digit(char c, bool hex = false)
|
|
|
|
{
|
|
|
|
return (digit(c, hex) >= 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return true if character is whitespace
|
|
|
|
*/
|
|
|
|
inline bool is_whitespace(char c)
|
|
|
|
{
|
|
|
|
return (c == '\t' || c == ' ' || c == '\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read unsigned long value from string
|
2015-04-10 15:45:35 +00:00
|
|
|
*
|
|
|
|
* \param s source string
|
|
|
|
* \param result destination variable
|
|
|
|
* \param base integer base
|
|
|
|
* \return number of consumed characters
|
|
|
|
*
|
|
|
|
* If the base argument is 0, the integer base is detected based on the
|
|
|
|
* characters in front of the number. If the number is prefixed with "0x",
|
|
|
|
* a base of 16 is used, otherwise a base of 10.
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2015-11-05 19:37:08 +00:00
|
|
|
template <typename T>
|
|
|
|
inline size_t ascii_to_unsigned(const char *s, T &result, unsigned base)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2015-11-05 19:37:08 +00:00
|
|
|
T i = 0, value = 0;
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
if (!*s) return i;
|
|
|
|
|
|
|
|
/* autodetect hexadecimal base, default is a base of 10 */
|
|
|
|
if (base == 0) {
|
|
|
|
|
|
|
|
/* read '0x' prefix */
|
|
|
|
if (*s == '0' && (s[1] == 'x' || s[1] == 'X')) {
|
|
|
|
s += 2; i += 2;
|
|
|
|
base = 16;
|
|
|
|
} else
|
|
|
|
base = 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* read number */
|
|
|
|
for (int d; ; s++, i++) {
|
|
|
|
|
|
|
|
/* read digit, stop when hitting a non-digit character */
|
|
|
|
if ((d = digit(*s, base == 16)) < 0) break;
|
|
|
|
|
|
|
|
/* append digit to integer value */
|
|
|
|
value = value*base + d;
|
|
|
|
}
|
|
|
|
|
2015-04-10 15:45:35 +00:00
|
|
|
result = value;
|
2011-12-22 15:19:25 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-08-28 12:42:22 +00:00
|
|
|
/**
|
|
|
|
* Read boolean value from string
|
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
|
|
|
*/
|
|
|
|
inline size_t ascii_to(char const *s, bool &result)
|
|
|
|
{
|
|
|
|
if (!strcmp(s, "yes", 3)) { result = true; return 3; }
|
|
|
|
if (!strcmp(s, "true", 4)) { result = true; return 4; }
|
|
|
|
if (!strcmp(s, "on", 2)) { result = true; return 2; }
|
|
|
|
if (!strcmp(s, "no", 2)) { result = false; return 2; }
|
|
|
|
if (!strcmp(s, "false", 5)) { result = false; return 5; }
|
|
|
|
if (!strcmp(s, "off", 3)) { result = false; return 3; }
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-27 14:51:34 +00:00
|
|
|
/**
|
|
|
|
* Read unsigned char value from string
|
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
|
|
|
*/
|
|
|
|
inline size_t ascii_to(const char *s, unsigned char &result)
|
|
|
|
{
|
|
|
|
return ascii_to_unsigned(s, result, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-02-11 13:46:43 +00:00
|
|
|
/**
|
|
|
|
* Read unsigned short value from string
|
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
|
|
|
*/
|
|
|
|
inline size_t ascii_to(const char *s, unsigned short &result)
|
|
|
|
{
|
|
|
|
return ascii_to_unsigned(s, result, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-04-10 15:45:35 +00:00
|
|
|
/**
|
|
|
|
* Read unsigned long value from string
|
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
|
|
|
*/
|
|
|
|
inline size_t ascii_to(const char *s, unsigned long &result)
|
|
|
|
{
|
2015-11-05 19:37:08 +00:00
|
|
|
return ascii_to_unsigned(s, result, 0);
|
2015-04-10 15:45:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-11-05 19:37:08 +00:00
|
|
|
/**
|
|
|
|
* Read unsigned long long value from string
|
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
|
|
|
*/
|
|
|
|
inline size_t ascii_to(const char *s, unsigned long long &result)
|
|
|
|
{
|
|
|
|
return ascii_to_unsigned(s, result, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-12-22 15:19:25 +00:00
|
|
|
/**
|
|
|
|
* Read unsigned int value from string
|
2015-04-10 15:45:35 +00:00
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2015-04-10 15:45:35 +00:00
|
|
|
inline size_t ascii_to(const char *s, unsigned int &result)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
2015-11-05 19:37:08 +00:00
|
|
|
return ascii_to_unsigned(s, result, 0);
|
2011-12-22 15:19:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read signed long value from string
|
2015-04-10 15:45:35 +00:00
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2015-04-10 15:45:35 +00:00
|
|
|
inline size_t ascii_to(const char *s, long &result)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
/* read sign */
|
|
|
|
int sign = (*s == '-') ? -1 : 1;
|
|
|
|
|
|
|
|
if (*s == '-' || *s == '+') { s++; i++; }
|
|
|
|
|
|
|
|
int j = 0;
|
|
|
|
unsigned long value = 0;
|
|
|
|
|
2015-11-05 19:37:08 +00:00
|
|
|
j = ascii_to_unsigned(s, value, 10);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
if (!j) return i;
|
|
|
|
|
2015-04-10 15:45:35 +00:00
|
|
|
result = sign*value;
|
2011-12-22 15:19:25 +00:00
|
|
|
return i + j;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read 'Number_of_bytes' value from string and handle the size suffixes
|
|
|
|
*
|
|
|
|
* This function scales the resulting size value according to the suffixes
|
|
|
|
* for G (2^30), M (2^20), and K (2^10) if present.
|
2015-04-10 15:45:35 +00:00
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2015-04-10 15:45:35 +00:00
|
|
|
inline size_t ascii_to(const char *s, Number_of_bytes &result)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
|
|
|
unsigned long res = 0;
|
|
|
|
|
|
|
|
/* convert numeric part of string */
|
2015-11-05 19:37:08 +00:00
|
|
|
int i = ascii_to_unsigned(s, res, 0);
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
/* handle suffixes */
|
|
|
|
if (i > 0)
|
|
|
|
switch (s[i]) {
|
|
|
|
case 'G': res *= 1024;
|
|
|
|
case 'M': res *= 1024;
|
|
|
|
case 'K': res *= 1024; i++;
|
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
|
2015-04-10 15:45:35 +00:00
|
|
|
result = res;
|
2011-12-22 15:19:25 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read double float value from string
|
2015-04-10 15:45:35 +00:00
|
|
|
*
|
|
|
|
* \return number of consumed characters
|
2011-12-22 15:19:25 +00:00
|
|
|
*/
|
2015-04-10 15:45:35 +00:00
|
|
|
inline size_t ascii_to(const char *s, double &result)
|
2011-12-22 15:19:25 +00:00
|
|
|
{
|
|
|
|
double v = 0.0; /* decimal part */
|
|
|
|
double d = 0.1; /* power of fractional digit */
|
|
|
|
bool neg = false; /* sign */
|
|
|
|
int i = 0; /* character counter */
|
|
|
|
|
|
|
|
if (s[i] == '-') {
|
|
|
|
neg = true;
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* parse decimal part of number */
|
|
|
|
for (; s[i] && is_digit(s[i]); i++)
|
|
|
|
v = 10*v + digit(s[i], false);
|
|
|
|
|
|
|
|
/* if no fractional part exists, return current value */
|
|
|
|
if (s[i] != '.') {
|
2015-04-10 15:45:35 +00:00
|
|
|
result = neg ? -v : v;
|
2011-12-22 15:19:25 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* skip comma */
|
|
|
|
i++;
|
|
|
|
|
|
|
|
/* parse fractional part of number */
|
|
|
|
for (; s[i] && is_digit(s[i]); i++, d *= 0.1)
|
|
|
|
v += d*digit(s[i], false);
|
|
|
|
|
2015-04-10 15:45:35 +00:00
|
|
|
result = neg ? -v : v;
|
2011-12-22 15:19:25 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check for end of quotation
|
|
|
|
*
|
|
|
|
* Checks if next character is non-backslashed quotation mark.
|
|
|
|
*/
|
|
|
|
inline bool end_of_quote(const char *s) {
|
|
|
|
return s[0] != '\\' && s[1] == '\"'; }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unpack quoted string
|
|
|
|
*
|
|
|
|
* \param src source string including the quotation marks ("...")
|
|
|
|
* \param dst destination buffer
|
|
|
|
*
|
|
|
|
* \return number of characters or negative error code
|
|
|
|
*/
|
|
|
|
inline int unpack_string(const char *src, char *dst, int dst_len)
|
|
|
|
{
|
|
|
|
/* check if quoted string */
|
|
|
|
if (*src != '"') return -1;
|
|
|
|
|
|
|
|
src++;
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
for (; *src && !end_of_quote(src - 1) && (i < dst_len - 1); i++) {
|
|
|
|
|
|
|
|
/* transform '\"' to '"' */
|
|
|
|
if (src[0] == '\\' && src[1] == '\"') {
|
|
|
|
*dst++ = '"';
|
|
|
|
src += 2;
|
|
|
|
} else
|
|
|
|
*dst++ = *src++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* write terminating null */
|
|
|
|
*dst = 0;
|
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
2015-03-04 20:12:14 +00:00
|
|
|
}
|
2013-09-19 18:35:45 +00:00
|
|
|
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
/**
|
|
|
|
* Helper for the formatted output of a length-constrained character buffer
|
|
|
|
*/
|
|
|
|
class Genode::Cstring
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
|
|
|
|
char const * const _str;
|
|
|
|
size_t const _len;
|
|
|
|
|
|
|
|
static size_t _init_len(char const *str, size_t max_len)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* In contrast to 'strlen' we stop searching for a terminating
|
|
|
|
* null once we reach 'max_len'.
|
|
|
|
*/
|
|
|
|
size_t res = 0;
|
|
|
|
for (; str && *str && res < max_len; str++, res++);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* \param str null-terminated character buffer
|
|
|
|
*/
|
|
|
|
Cstring(char const *str) : _str(str), _len(strlen(str)) { }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* \param str character buffer, not neccessarily null-terminated
|
|
|
|
* \param max_len maximum number of characters to consume
|
|
|
|
*
|
|
|
|
* The 'Cstring' contains all characters up to a terminating null in
|
|
|
|
* the 'str' buffer but not more that 'max_len' characters.
|
|
|
|
*/
|
|
|
|
Cstring(char const *str, size_t max_len)
|
|
|
|
:
|
|
|
|
_str(str), _len(_init_len(str, max_len))
|
|
|
|
{ }
|
|
|
|
|
|
|
|
void print(Output &out) const { out.out_string(_str, _len); }
|
2016-10-28 10:12:08 +00:00
|
|
|
|
|
|
|
size_t length() const { return _len; }
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
/**
|
|
|
|
* Buffer that contains a null-terminated string
|
|
|
|
*
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
* \param CAPACITY buffer size including the terminating zero,
|
|
|
|
* must be higher than zero
|
2015-03-04 20:12:14 +00:00
|
|
|
*/
|
|
|
|
template <Genode::size_t CAPACITY>
|
|
|
|
class Genode::String
|
|
|
|
{
|
|
|
|
private:
|
2013-09-19 18:35:45 +00:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
char _buf[CAPACITY];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Number of chars contained in '_buf' including the terminating null
|
|
|
|
*/
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
size_t _len { 0 };
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Output facility that targets a character buffer
|
|
|
|
*/
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
class Local_output : public Output
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
{
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
private:
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
/*
|
|
|
|
* Noncopyable
|
|
|
|
*/
|
|
|
|
Local_output(Local_output const &);
|
|
|
|
Local_output &operator = (Local_output const &);
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
public:
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
char * const _buf;
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
size_t _num_chars = 0;
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
/**
|
|
|
|
* Return true if '_buf' can fit at least one additional 'char'.
|
|
|
|
*/
|
|
|
|
bool _capacity_left() const { return CAPACITY - _num_chars - 1; }
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
void _append(char c) { _buf[_num_chars++] = c; }
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
Local_output(char *buf) : _buf(buf) { }
|
|
|
|
|
|
|
|
size_t num_chars() const { return _num_chars; }
|
|
|
|
|
|
|
|
void out_char(char c) override { if (_capacity_left()) _append(c); }
|
|
|
|
|
|
|
|
void out_string(char const *str, size_t n) override
|
|
|
|
{
|
|
|
|
while (n-- > 0 && _capacity_left() && *str)
|
|
|
|
_append(*str++);
|
|
|
|
}
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
};
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
public:
|
2013-09-19 18:35:45 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
constexpr static size_t size() { return CAPACITY; }
|
2013-09-19 18:35:45 +00:00
|
|
|
|
Follow practices suggested by "Effective C++"
The patch adjust the code of the base, base-<kernel>, and os repository.
To adapt existing components to fix violations of the best practices
suggested by "Effective C++" as reported by the -Weffc++ compiler
argument. The changes follow the patterns outlined below:
* A class with virtual functions can no longer publicly inherit base
classed without a vtable. The inherited object may either be moved
to a member variable, or inherited privately. The latter would be
used for classes that inherit 'List::Element' or 'Avl_node'. In order
to enable the 'List' and 'Avl_tree' to access the meta data, the
'List' must become a friend.
* Instead of adding a virtual destructor to abstract base classes,
we inherit the new 'Interface' class, which contains a virtual
destructor. This way, single-line abstract base classes can stay
as compact as they are now. The 'Interface' utility resides in
base/include/util/interface.h.
* With the new warnings enabled, all member variables must be explicitly
initialized. Basic types may be initialized with '='. All other types
are initialized with braces '{ ... }' or as class initializers. If
basic types and non-basic types appear in a row, it is nice to only
use the brace syntax (also for basic types) and align the braces.
* If a class contains pointers as members, it must now also provide a
copy constructor and assignment operator. In the most cases, one
would make them private, effectively disallowing the objects to be
copied. Unfortunately, this warning cannot be fixed be inheriting
our existing 'Noncopyable' class (the compiler fails to detect that
the inheriting class cannot be copied and still gives the error).
For now, we have to manually add declarations for both the copy
constructor and assignment operator as private class members. Those
declarations should be prepended with a comment like this:
/*
* Noncopyable
*/
Thread(Thread const &);
Thread &operator = (Thread const &);
In the future, we should revisit these places and try to replace
the pointers with references. In the presence of at least one
reference member, the compiler would no longer implicitly generate
a copy constructor. So we could remove the manual declaration.
Issue #465
2017-12-21 14:42:15 +00:00
|
|
|
String() { }
|
2013-09-19 18:35:45 +00:00
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
2016-10-25 09:39:24 +00:00
|
|
|
* The constructor accepts a non-zero number of arguments, which
|
|
|
|
* are concatenated in the resulting 'String' object. In order to
|
|
|
|
* generate the textual representation of the arguments, the
|
|
|
|
* argument types must support the 'Output' interface, e.g., by
|
|
|
|
* providing 'print' method.
|
|
|
|
*
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
* If the textual representation of the supplied arguments exceeds
|
|
|
|
* 'CAPACITY', the resulting string gets truncated. The caller may
|
|
|
|
* check for this condition by evaluating the 'length' of the
|
|
|
|
* constructed 'String'. If 'length' equals 'CAPACITY', the string
|
|
|
|
* may fit perfectly into the buffer or may have been truncated.
|
|
|
|
* In general, it would be safe to assume the latter.
|
|
|
|
*/
|
2016-10-25 09:39:24 +00:00
|
|
|
template <typename T, typename... TAIL>
|
|
|
|
String(T const &arg, TAIL &&... args)
|
|
|
|
{
|
|
|
|
/* initialize string content */
|
|
|
|
Local_output output(_buf);
|
|
|
|
Genode::print(output, arg, args...);
|
|
|
|
|
|
|
|
/* add terminating null */
|
|
|
|
_buf[output.num_chars()] = 0;
|
|
|
|
_len = output.num_chars() + 1;
|
|
|
|
}
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
|
2016-10-28 10:12:08 +00:00
|
|
|
/**
|
|
|
|
* Constructor
|
|
|
|
*
|
|
|
|
* Overload for the common case of constructing a 'String' from a
|
|
|
|
* string literal.
|
|
|
|
*/
|
|
|
|
String(char const *cstr) : _len(min(Genode::strlen(cstr) + 1, CAPACITY))
|
|
|
|
{
|
|
|
|
Genode::strncpy(_buf, cstr, _len);
|
|
|
|
}
|
|
|
|
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
/**
|
|
|
|
* Copy constructor
|
|
|
|
*/
|
|
|
|
template <unsigned N>
|
2016-09-05 08:49:39 +00:00
|
|
|
String(String<N> const &other) : _len(min(other.length(), CAPACITY))
|
2015-03-04 20:12:14 +00:00
|
|
|
{
|
2016-09-05 08:49:39 +00:00
|
|
|
Genode::strncpy(_buf, other.string(), _len);
|
2015-03-04 20:12:14 +00:00
|
|
|
}
|
2014-01-10 11:30:07 +00:00
|
|
|
|
2016-05-09 10:36:15 +00:00
|
|
|
/**
|
|
|
|
* Return length of string, including the terminating null character
|
|
|
|
*/
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
size_t length() const { return _len; }
|
2014-01-10 11:30:07 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
static constexpr size_t capacity() { return CAPACITY; }
|
2013-09-19 18:35:45 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
bool valid() const {
|
base: avoid use of deprecated base/printf.h
Besides adapting the components to the use of base/log.h, the patch
cleans up a few base headers, i.e., it removes unused includes from
root/component.h, specifically base/heap.h and
ram_session/ram_session.h. Hence, components that relied on the implicit
inclusion of those headers have to manually include those headers now.
While adjusting the log messages, I repeatedly stumbled over the problem
that printing char * arguments is ambiguous. It is unclear whether to
print the argument as pointer or null-terminated string. To overcome
this problem, the patch introduces a new type 'Cstring' that allows the
caller to express that the argument should be handled as null-terminated
string. As a nice side effect, with this type in place, the optional len
argument of the 'String' class could be removed. Instead of supplying a
pair of (char const *, size_t), the constructor accepts a 'Cstring'.
This, in turn, clears the way let the 'String' constructor use the new
output mechanism to assemble a string from multiple arguments (and
thereby getting rid of snprintf within Genode in the near future).
To enforce the explicit resolution of the char * ambiguity, the 'char *'
overload of the 'print' function is marked as deleted.
Issue #1987
2016-07-13 17:07:09 +00:00
|
|
|
return (_len <= CAPACITY) && (_len != 0) && (_buf[_len - 1] == '\0'); }
|
2014-01-11 23:00:53 +00:00
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
char const *string() const { return valid() ? _buf : ""; }
|
2014-10-01 10:42:44 +00:00
|
|
|
|
2015-10-05 13:42:24 +00:00
|
|
|
bool operator == (char const *other) const
|
|
|
|
{
|
|
|
|
return strcmp(string(), other) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator != (char const *other) const
|
|
|
|
{
|
|
|
|
return strcmp(string(), other) != 0;
|
|
|
|
}
|
|
|
|
|
2015-03-04 20:12:14 +00:00
|
|
|
template <size_t OTHER_CAPACITY>
|
|
|
|
bool operator == (String<OTHER_CAPACITY> const &other) const
|
|
|
|
{
|
|
|
|
return strcmp(string(), other.string()) == 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <size_t OTHER_CAPACITY>
|
|
|
|
bool operator != (String<OTHER_CAPACITY> const &other) const
|
|
|
|
{
|
|
|
|
return strcmp(string(), other.string()) != 0;
|
|
|
|
}
|
2016-07-13 13:15:03 +00:00
|
|
|
|
|
|
|
void print(Output &out) const { Genode::print(out, string()); }
|
2015-03-04 20:12:14 +00:00
|
|
|
};
|
2011-12-22 15:19:25 +00:00
|
|
|
|
|
|
|
#endif /* _INCLUDE__UTIL__STRING_H_ */
|