mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
sys: fmt: initial commit of simple string formatting library
This commit is contained in:
parent
de539fa54f
commit
1293e7a8b9
1
sys/fmt/Makefile
Normal file
1
sys/fmt/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
178
sys/fmt/fmt.c
Normal file
178
sys/fmt/fmt.c
Normal file
@ -0,0 +1,178 @@
|
||||
/**
|
||||
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
* @ingroup sys_fmt
|
||||
* @{
|
||||
* @file
|
||||
* @brief String formatting library implementation
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "div.h"
|
||||
#include "fmt.h"
|
||||
|
||||
static const char _hex_chars[16] = "0123456789ABCDEF";
|
||||
|
||||
static inline int _is_digit(char c)
|
||||
{
|
||||
return (c >= '0' && c <= '9');
|
||||
}
|
||||
|
||||
size_t fmt_byte_hex(char *out, uint8_t byte)
|
||||
{
|
||||
if (out) {
|
||||
*out++ = _hex_chars[byte >> 4];
|
||||
*out = _hex_chars[byte & 0x0F];
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
size_t fmt_strlen(const char *str)
|
||||
{
|
||||
const char *tmp = str;
|
||||
while(*tmp) {
|
||||
tmp++;
|
||||
}
|
||||
return (tmp - str);
|
||||
}
|
||||
|
||||
size_t fmt_str(char *out, const char *str)
|
||||
{
|
||||
int len = 0;
|
||||
if (!out) {
|
||||
len = fmt_strlen(str);
|
||||
} else {
|
||||
char c;
|
||||
while ((c = *str++)) {
|
||||
*out++ = c;
|
||||
len++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t fmt_bytes_hex_reverse(char *out, const uint8_t *ptr, size_t n)
|
||||
{
|
||||
size_t i = n;
|
||||
while (i--) {
|
||||
out += fmt_byte_hex(out, ptr[i]);
|
||||
}
|
||||
return (n<<1);
|
||||
}
|
||||
|
||||
size_t fmt_u32_hex(char *out, uint32_t val)
|
||||
{
|
||||
return fmt_bytes_hex_reverse(out, (uint8_t*) &val, 4);
|
||||
}
|
||||
|
||||
size_t fmt_u64_hex(char *out, uint64_t val)
|
||||
{
|
||||
return fmt_bytes_hex_reverse(out, (uint8_t*) &val, 8);
|
||||
}
|
||||
|
||||
size_t fmt_u32_dec(char *out, uint32_t val)
|
||||
{
|
||||
size_t len = 1;
|
||||
|
||||
/* count needed characters */
|
||||
for (uint32_t tmp = val; (tmp > 9); len++) {
|
||||
tmp = div_u32_by_10(tmp);
|
||||
}
|
||||
|
||||
if (out) {
|
||||
char *ptr = out + len;
|
||||
while(val) {
|
||||
*--ptr = div_u32_mod_10(val) + '0';
|
||||
val = div_u32_by_10(val);
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t fmt_u16_dec(char *out, uint16_t val)
|
||||
{
|
||||
return fmt_u32_dec(out, val);
|
||||
}
|
||||
|
||||
size_t fmt_s32_dec(char *out, int32_t val)
|
||||
{
|
||||
int negative = (val < 0);
|
||||
if (negative) {
|
||||
if (out) {
|
||||
*out++ = '-';
|
||||
}
|
||||
val *= -1;
|
||||
}
|
||||
return fmt_u32_dec(out, val) + negative;
|
||||
}
|
||||
|
||||
uint32_t scn_u32_dec(const char *str, size_t n)
|
||||
{
|
||||
uint32_t res = 0;
|
||||
while(n--) {
|
||||
char c = *str++;
|
||||
if (!_is_digit(c)) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
res *= 10;
|
||||
res += (c - '0');
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void print(const char *s, size_t n)
|
||||
{
|
||||
while (n > 0) {
|
||||
ssize_t written = write(STDOUT_FILENO, s, n);
|
||||
if (written < 0) {
|
||||
break;
|
||||
}
|
||||
n -= written;
|
||||
s += written;
|
||||
}
|
||||
}
|
||||
|
||||
void print_u32_dec(uint32_t val)
|
||||
{
|
||||
char buf[10];
|
||||
size_t len = fmt_u32_dec(buf, val);
|
||||
print(buf, len);
|
||||
}
|
||||
|
||||
void print_s32_dec(int32_t val)
|
||||
{
|
||||
char buf[11];
|
||||
size_t len = fmt_s32_dec(buf, val);
|
||||
print(buf, len);
|
||||
}
|
||||
|
||||
void print_u32_hex(uint32_t val)
|
||||
{
|
||||
char buf[8];
|
||||
fmt_u32_hex(buf, val);
|
||||
print(buf, sizeof(buf));
|
||||
}
|
||||
|
||||
void print_u64_hex(uint64_t val)
|
||||
{
|
||||
print_u32_hex(val>>32);
|
||||
print_u32_hex(val);
|
||||
}
|
||||
|
||||
void print_str(const char* str)
|
||||
{
|
||||
print(str, fmt_strlen(str));
|
||||
}
|
214
sys/include/fmt.h
Normal file
214
sys/include/fmt.h
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sys_fmt string formatting
|
||||
* @ingroup sys
|
||||
* @brief Provides simple string formatting functions
|
||||
*
|
||||
* @{
|
||||
* @file
|
||||
* @brief string formatting API
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#ifndef FMT_H_
|
||||
#define FMT_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Format a byte value as hex
|
||||
*
|
||||
* E.g., converts byte value 0 to the string 00, 255 to the string FF.
|
||||
*
|
||||
* Will write two bytes to @p out.
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] byte Byte value to convert
|
||||
*
|
||||
* @return 2
|
||||
*/
|
||||
size_t fmt_byte_hex(char *out, uint8_t byte);
|
||||
|
||||
/**
|
||||
* @brief Formats a sequence of bytes as hex bytes, starting with the last byte
|
||||
*
|
||||
* Will write 2*n bytes to @p out.
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] ptr Pointer to bytes to convert
|
||||
* @param[in] n Number of bytes to convert
|
||||
*
|
||||
* @return 2*n
|
||||
*/
|
||||
size_t fmt_bytes_hex_reverse(char *out, const uint8_t *ptr, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Convert a uint32 value to hex string.
|
||||
*
|
||||
* Will write 8 bytes to @p out.
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] val Value to convert
|
||||
*
|
||||
* @return 8
|
||||
*/
|
||||
size_t fmt_u32_hex(char *out, uint32_t val);
|
||||
|
||||
/**
|
||||
* @brief Convert a uint64 value to hex string.
|
||||
*
|
||||
* Will write 16 bytes to @p out.
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] val Value to convert
|
||||
*
|
||||
* @return 16
|
||||
*/
|
||||
size_t fmt_u64_hex(char *out, uint64_t val);
|
||||
|
||||
/**
|
||||
* @brief Convert a uint32 value to decimal string.
|
||||
*
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] val Value to convert
|
||||
*
|
||||
* @return nr of digits written to (or needed in) @p out
|
||||
*/
|
||||
size_t fmt_u32_dec(char *out, uint32_t val);
|
||||
|
||||
/**
|
||||
* @brief Convert a uint16 value to decimal string.
|
||||
*
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] val Value to convert
|
||||
*
|
||||
* @return nr of digits written to (or needed in) @p out
|
||||
*/
|
||||
size_t fmt_u16_dec(char *out, uint16_t val);
|
||||
|
||||
/**
|
||||
* @brief Convert a int32 value to decimal string.
|
||||
*
|
||||
* Will add a leading "-" if @p val is negative.
|
||||
*
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] val Value to convert
|
||||
*
|
||||
* @return nr of characters written to (or needed in) @p out
|
||||
*/
|
||||
size_t fmt_s32_dec(char *out, int32_t val);
|
||||
|
||||
/**
|
||||
* @brief Count characters until '\0' (exclusive) in @p str
|
||||
*
|
||||
* @param[in] str Pointer to string
|
||||
*
|
||||
* @return nr of characters in string @p str points to
|
||||
*/
|
||||
size_t fmt_strlen(const char *str);
|
||||
|
||||
/**
|
||||
* @brief Copy null-terminated string (excluding terminating \0)
|
||||
*
|
||||
* If @p out is NULL, will only return the number of bytes that would have
|
||||
* been written.
|
||||
*
|
||||
* @param[out] out Pointer to output buffer, or NULL
|
||||
* @param[in] str Pointer to null-terminated source string
|
||||
*
|
||||
* @return nr of characters written to (or needed in) @p out
|
||||
*/
|
||||
size_t fmt_str(char *out, const char *str);
|
||||
|
||||
/**
|
||||
* @brief Convert digits to uint32
|
||||
*
|
||||
* Will convert up to @p n digits. Stops at any non-digit or '\0' character.
|
||||
*
|
||||
* @param[out] str Pointer to string to read from
|
||||
* @param[in] n Maximum nr of characters to consider
|
||||
*
|
||||
* @return nr of digits read
|
||||
*/
|
||||
uint32_t scn_u32_dec(const char *str, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Print string to stdout
|
||||
*
|
||||
* Writes @p n bytes from @p s to STDOUT_FILENO.
|
||||
*
|
||||
* @param[out] s Pointer to string to print
|
||||
* @param[in] n Number of bytes to print
|
||||
*/
|
||||
void print(const char* s, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Print uint32 value to stdout
|
||||
*
|
||||
* @param[in] val Value to print
|
||||
*/
|
||||
void print_u32_dec(uint32_t val);
|
||||
|
||||
/**
|
||||
* @brief Print int32 value to stdout
|
||||
*
|
||||
* @param[in] val Value to print
|
||||
*/
|
||||
void print_s32_dec(int32_t val);
|
||||
|
||||
/**
|
||||
* @brief Print uint32 value as hex to stdout
|
||||
*
|
||||
* @param[in] val Value to print
|
||||
*/
|
||||
void print_u32_hex(uint32_t val);
|
||||
|
||||
/**
|
||||
* @brief Print uint64 value as hex to stdout
|
||||
*
|
||||
* @param[in] val Value to print
|
||||
*/
|
||||
void print_u64_hex(uint64_t val);
|
||||
|
||||
/**
|
||||
* @brief Print null-terminated string to stdout
|
||||
*
|
||||
* @param[in] str Pointer to string to print
|
||||
*/
|
||||
void print_str(const char* str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif /* FMT_H_ */
|
Loading…
Reference in New Issue
Block a user