mirror of
https://github.com/genodelabs/genode.git
synced 2025-06-17 22:58:26 +00:00
Move XML util from os to base repository
Since the dynamic linker depends on the XML utils and we plan to replace the ancient 'Arg_string' with XML, it is time to move the 'Xml_node' and 'Xml_generator' to base/include.
This commit is contained in:
committed by
Christian Helmuth
parent
73b463cdbb
commit
2bc8a0f76a
96
repos/base/include/util/print_lines.h
Normal file
96
repos/base/include/util/print_lines.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* \brief Utility for safely writing multi-line text
|
||||
* \author Norman Feske
|
||||
* \date 2014-01-11
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2014 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU General Public License version 2.
|
||||
*/
|
||||
|
||||
#ifndef _INCLUDE__UTIL__PRINT_LINES_H_
|
||||
#define _INCLUDE__UTIL__PRINT_LINES_H_
|
||||
|
||||
#include <util/string.h>
|
||||
|
||||
namespace Genode {
|
||||
|
||||
template <size_t, typename FUNC>
|
||||
static inline void print_lines(char const *, size_t, FUNC const &);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Print multi-line string
|
||||
*
|
||||
* \param MAX_LINE_LEN maximum line length, used to dimension a line buffer
|
||||
* on the stack
|
||||
* \param string character buffer, not necessarily null-terminated
|
||||
* \param len number of characters to print
|
||||
* \param func functor called for each line with 'char const *' as
|
||||
* argument
|
||||
*
|
||||
* In situations where a string is supplied by an untrusted client, we cannot
|
||||
* simply print the client-provided content as a single string becausewe cannot
|
||||
* expect the client to null-terminate the string properly. The 'Log_multiline'
|
||||
* class outputs the content line by line while keeping track of the content
|
||||
* size.
|
||||
*
|
||||
* The output stops when reaching the end of the buffer or when a null
|
||||
* character is encountered.
|
||||
*/
|
||||
template <Genode::size_t MAX_LINE_LEN, typename FUNC>
|
||||
void Genode::print_lines(char const *string, size_t len, FUNC const &func)
|
||||
{
|
||||
/* skip leading line breaks */
|
||||
for (; *string == '\n'; string++);
|
||||
|
||||
/* number of space and tab characters used for indentation */
|
||||
size_t const num_indent_chars =
|
||||
({
|
||||
size_t n = 0;
|
||||
for (; string[n] == ' ' || string[n] == '\t'; n++);
|
||||
n;
|
||||
});
|
||||
|
||||
char const * const first_line = string;
|
||||
|
||||
while (*string && len) {
|
||||
|
||||
/*
|
||||
* Skip indentation if the pattern is the same as for the first line.
|
||||
*/
|
||||
if (Genode::strcmp(first_line, string, num_indent_chars) == 0)
|
||||
string += num_indent_chars;
|
||||
|
||||
size_t const line_len =
|
||||
({
|
||||
size_t i = 0;
|
||||
for (; string[i] && i < len && string[i] != '\n'; i++);
|
||||
|
||||
/* the newline character belongs to the line */
|
||||
if (string[i] == '\n')
|
||||
i++;
|
||||
|
||||
i;
|
||||
});
|
||||
|
||||
if (!line_len)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Copy line from (untrusted) caller to local line buffer
|
||||
*/
|
||||
char line_buf[MAX_LINE_LEN];
|
||||
Genode::strncpy(line_buf, string, Genode::min(line_len + 1, sizeof(line_buf)));
|
||||
func(line_buf);
|
||||
|
||||
string += line_len;
|
||||
len -= line_len;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _INCLUDE__UTIL__PRINT_LINES_H_ */
|
Reference in New Issue
Block a user