From 527af2b7f2b27c19e27a8c2a47bbe5786fc66f47 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 25 Jul 2023 13:34:52 +0200 Subject: score: Move formatted I/O functions These functions do not belong to an super core service. --- cpukit/dev/iobase64.c | 111 +++++++++++++++ cpukit/dev/ioprintf.c | 53 +++++++ cpukit/dev/iovprintf.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 541 insertions(+) create mode 100644 cpukit/dev/iobase64.c create mode 100644 cpukit/dev/ioprintf.c create mode 100644 cpukit/dev/iovprintf.c (limited to 'cpukit/dev') diff --git a/cpukit/dev/iobase64.c b/cpukit/dev/iobase64.c new file mode 100644 index 0000000000..0ac70d3ddb --- /dev/null +++ b/cpukit/dev/iobase64.c @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: ISC */ + +/** + * @file + * + * @ingroup RTEMSDeviceIO + * + * @brief This source file contains the implementation of + * _IO_Base64() and _IO_Base64url(). + */ + +/* + * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG + * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 1998-2001, 2003 Internet Software Consortium. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +static void +_IO_Put(int c, void *arg, IO_Put_char put_char) +{ + (*put_char)(c, arg); +} + +static int +_IO_Base64_with_encoding(IO_Put_char put_char, void *arg, const void *src, + size_t srclen, const char *wordbreak, int wordlen, const char *encoding) +{ + unsigned int loops = 0; + const unsigned char *in = src; + int out = 0; + + if (wordlen < 4) { + wordlen = 4; + } + + while (srclen > 2) { + _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char); + _IO_Put(encoding[((in[0]<<4)&0x30)| + ((in[1]>>4)&0x0f)], arg, put_char); + _IO_Put(encoding[((in[1]<<2)&0x3c)| + ((in[2]>>6)&0x03)], arg, put_char); + _IO_Put(encoding[in[2]&0x3f], arg, put_char); + in += 3; + srclen -= 3; + out += 4; + + loops++; + if (srclen != 0 && + (int)((loops + 1) * 4) >= wordlen) + { + const char *w = wordbreak; + loops = 0; + while (*w != '\0') { + _IO_Put(*w, arg, put_char); + ++w; + ++out; + } + } + } + if (srclen == 2) { + _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char); + _IO_Put(encoding[((in[0]<<4)&0x30)| + ((in[1]>>4)&0x0f)], arg, put_char); + _IO_Put(encoding[((in[1]<<2)&0x3c)], arg, put_char); + _IO_Put('=', arg, put_char); + out += 4; + } else if (srclen == 1) { + _IO_Put(encoding[(in[0]>>2)&0x3f], arg, put_char); + _IO_Put(encoding[((in[0]<<4)&0x30)], arg, put_char); + _IO_Put('=', arg, put_char); + _IO_Put('=', arg, put_char); + out += 4; + } + return out; +} + +static const char base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; + +int +_IO_Base64(IO_Put_char put_char, void *arg, const void *src, size_t srclen, + const char *wordbreak, int wordlen) +{ + return _IO_Base64_with_encoding(put_char, arg, src, srclen, wordbreak, + wordlen, base64); +} + +static const char base64url[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_="; + +int +_IO_Base64url(IO_Put_char put_char, void *arg, const void *src, size_t srclen, + const char *wordbreak, int wordlen) +{ + return _IO_Base64_with_encoding(put_char, arg, src, srclen, wordbreak, + wordlen, base64url); +} diff --git a/cpukit/dev/ioprintf.c b/cpukit/dev/ioprintf.c new file mode 100644 index 0000000000..1f16389b47 --- /dev/null +++ b/cpukit/dev/ioprintf.c @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RTEMSDeviceIO + * + * @brief This source file contains the implementation of + * _IO_Printf(). + */ + +/* + * Copyright (c) 2017 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include + +int _IO_Printf( IO_Put_char put_char, void *arg, char const *fmt, ... ) +{ + va_list ap; + int len; + + va_start( ap, fmt ); + len = _IO_Vprintf( put_char, arg, fmt, ap ); + va_end( ap ); + + return len; +} diff --git a/cpukit/dev/iovprintf.c b/cpukit/dev/iovprintf.c new file mode 100644 index 0000000000..99b11b691d --- /dev/null +++ b/cpukit/dev/iovprintf.c @@ -0,0 +1,377 @@ +/** + * @file + * + * @ingroup RTEMSDeviceIO + * + * @brief This source file contains the implementation of + * _IO_Vprintf(). + */ + +/*- + * SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 1986, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + */ + +#include + +#include +__FBSDID("$FreeBSD: head/sys/kern/subr_prf.c 336417 2018-07-17 14:56:54Z markj $"); + +#include +#include + +/* Max number conversion buffer length: a intmax_t in base 8, plus NUL byte. */ +#define MAXNBUF (howmany(sizeof(intmax_t) * NBBY, 3) + 1) + +static inline int imax(int a, int b) { return (a > b ? a : b); } + +static char const hex2ascii_data[2][16] = { + { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' }, + { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'A', 'B', 'C', 'D', 'E', 'F' } +}; + +static inline char +hex2ascii(int hex) +{ + + return (hex2ascii_data[0][hex]); +} + +/* + * Put a NUL-terminated ASCII number (base <= 16) in a buffer in reverse + * order; return an optional length and a pointer to the last character + * written in the buffer (i.e., the first character of the string). + * The buffer pointed to by `nbuf' must have length >= MAXNBUF. + */ +static char * +ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) +{ + char *p; + + p = nbuf; + *p = '\0'; + do { + *++p = hex2ascii_data[upper][num % base]; + } while (num /= base); + if (lenp) + *lenp = p - nbuf; + return (p); +} + +int +_IO_Vprintf(IO_Put_char put_char, void *arg, char const *fmt, va_list ap) +{ +#define PCHAR(c) {int cc=(c); (*put_char)(cc, arg); retval++; } + char nbuf[MAXNBUF]; + const char *p, *percent, *q; + u_char *up; + int ch, n; + uintmax_t num; + int base, lflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + int cflag, hflag, jflag; + RTEMS_STATIC_ASSERT(sizeof(intmax_t) == sizeof(long long), _IO_Vprintf_j); +#if __SIZEOF_PTRDIFF_T__ == __SIZEOF_LONG__ +#define tflag lflag +#else + int tflag; +#endif +#if __SIZEOF_SIZE_T__ == __SIZEOF_LONG__ +#define zflag lflag +#else + int zflag; +#endif + int dwidth, upper; + char padc; + int stop = 0, retval = 0; + + num = 0; + + if (fmt == NULL) + fmt = "(fmt null)\n"; + + for (;;) { + padc = ' '; + width = 0; + while ((ch = (u_char)*fmt++) != '%' || stop) { + if (ch == '\0') + return (retval); + PCHAR(ch); + } + percent = fmt - 1; + lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + sign = 0; dot = 0; dwidth = 0; upper = 0; + cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; +reswitch: switch (ch = (u_char)*fmt++) { + case '.': + dot = 1; + goto reswitch; + case '#': + sharpflag = 1; + goto reswitch; + case '+': + sign = 1; + goto reswitch; + case '-': + ladjust = 1; + goto reswitch; + case '%': + PCHAR(ch); + break; + case '*': + if (!dot) { + width = va_arg(ap, int); + if (width < 0) { + ladjust = !ladjust; + width = -width; + } + } else { + dwidth = va_arg(ap, int); + } + goto reswitch; + case '0': + if (!dot) { + padc = '0'; + goto reswitch; + } + /* FALLTHROUGH */ + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (n = 0;; ++fmt) { + n = n * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + if (dot) + dwidth = n; + else + width = n; + goto reswitch; + case 'c': + width -= 1; + + if (!ladjust && width > 0) + while (width--) + PCHAR(padc); + PCHAR(va_arg(ap, int)); + if (ladjust && width > 0) + while (width--) + PCHAR(padc); + break; + case 'D': + up = va_arg(ap, u_char *); + p = va_arg(ap, char *); + if (!width) + width = 16; + while(width--) { + PCHAR(hex2ascii(*up >> 4)); + PCHAR(hex2ascii(*up & 0x0f)); + up++; + if (width) + for (q=p;*q;q++) + PCHAR(*q); + } + break; + case 'd': + case 'i': + base = 10; + sign = 1; + goto handle_sign; + case 'h': + if (hflag) { + hflag = 0; + cflag = 1; + } else + hflag = 1; + goto reswitch; + case 'j': + jflag = 1; + goto reswitch; + case 'l': + if (lflag) { + jflag = 1; + } else + lflag = 1; + goto reswitch; + case 'o': + base = 8; + goto handle_nosign; + case 'p': + base = 16; + sharpflag = (width == 0); + sign = 0; + num = (uintptr_t)va_arg(ap, void *); + goto number; + case 's': + p = va_arg(ap, char *); + if (p == NULL) + p = "(null)"; + if (!dot) + n = strlen (p); + else + for (n = 0; n < dwidth && p[n]; n++) + continue; + + width -= n; + + if (!ladjust && width > 0) + while (width--) + PCHAR(padc); + while (n--) + PCHAR(*p++); + if (ladjust && width > 0) + while (width--) + PCHAR(padc); + break; + case 't': + tflag = 1; + goto reswitch; + case 'u': + base = 10; + goto handle_nosign; + case 'X': + upper = 1; + case 'x': + base = 16; + goto handle_nosign; + case 'y': + base = 16; + sign = 1; + goto handle_sign; + case 'z': + zflag = 1; + goto reswitch; +handle_nosign: + sign = 0; + if (jflag) + num = va_arg(ap, uintmax_t); +#if __SIZEOF_PTRDIFF_T__ != __SIZEOF_LONG__ + else if (tflag) + num = va_arg(ap, ptrdiff_t); +#endif + else if (lflag) + num = va_arg(ap, u_long); +#if __SIZEOF_SIZE_T__ != __SIZEOF_LONG__ + else if (zflag) + num = va_arg(ap, size_t); +#endif + else if (hflag) + num = (u_short)va_arg(ap, int); + else if (cflag) + num = (u_char)va_arg(ap, int); + else + num = va_arg(ap, u_int); + goto number; +handle_sign: + if (jflag) + num = va_arg(ap, intmax_t); +#if __SIZEOF_PTRDIFF_T__ == __SIZEOF_LONG__ + else if (tflag) + num = va_arg(ap, ptrdiff_t); +#endif + else if (lflag) + num = va_arg(ap, long); +#if __SIZEOF_SIZE_T__ == __SIZEOF_LONG__ + else if (zflag) + num = va_arg(ap, ssize_t); +#endif + else if (hflag) + num = (short)va_arg(ap, int); + else if (cflag) + num = (char)va_arg(ap, int); + else + num = va_arg(ap, int); +number: + if (sign && (intmax_t)num < 0) { + neg = 1; + num = -(intmax_t)num; + } + p = ksprintn(nbuf, num, base, &n, upper); + tmp = 0; + if (sharpflag && num != 0) { + if (base == 8) + tmp++; + else if (base == 16) + tmp += 2; + } + if (neg) + tmp++; + + if (!ladjust && padc == '0') + dwidth = width - tmp; + width -= tmp + imax(dwidth, n); + dwidth -= n; + if (!ladjust) + while (width-- > 0) + PCHAR(' '); + if (neg) + PCHAR('-'); + if (sharpflag && num != 0) { + if (base == 8) { + PCHAR('0'); + } else if (base == 16) { + PCHAR('0'); + PCHAR('x'); + } + } + while (dwidth-- > 0) + PCHAR('0'); + + while (*p) + PCHAR(*p--); + + if (ladjust) + while (width-- > 0) + PCHAR(' '); + + break; + default: + while (percent < fmt) + PCHAR(*percent++); + /* + * Since we ignore a formatting argument it is no + * longer safe to obey the remaining formatting + * arguments as the arguments will no longer match + * the format specs. + */ + stop = 1; + break; + } + } +#undef PCHAR +} -- cgit v1.2.3