Toggle navigation
Documentation
The friendly Operating System for the Internet of Things
Loading...
Searching...
No Matches
stdio.h
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2023 Otto-von-Guericke-Universität Magdeburg
3
*
4
* This file is subject to the terms and conditions of the GNU Lesser General
5
* Public License v2.1. See the file LICENSE in the top level directory for more
6
* details.
7
*/
8
24
#ifndef STDIO_H
25
#define STDIO_H
26
#include_next "stdio.h"
27
28
/* C++ does not support __flash. Hence, only wrap printf() and friends for
29
* C and let C++ use them unmodified. */
30
#ifdef __cplusplus
31
extern
"C"
{
32
}
33
#else
34
35
#include "
flash_utils.h
"
36
37
#ifdef DOXYGEN
60
#define printf(...)
/* implementation details */
61
#else
62
/* this helper function-like macro takes at least 65 arguments and will
63
* "return" the 65 argument unmodified. It is not useful by itself, but
64
* needed to implement _SINGLEARG_OR_MULTIARG(). */
65
#define _TAKE_65TH_TOKEN( _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
66
_11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
67
_21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
68
_31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
69
_41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
70
_51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
71
_61, _62, _63, _64, N, ...) N
72
73
#define _EXPAND_HELPER(x) x
74
/* this function-like macro expands its argument */
75
#define _EXPAND(x) _EXPAND_HELPER(x)
76
77
/* This function-like macro will expand to `SINGLEARG` if called with one
78
* argument and `MULTIARG` if called with more than one.
79
*
80
* (Implementation detail: It will not work with more than 64 arguments. But
81
* 64 arguments to one printf call ought to be enough for everyone...)
82
*/
83
#define _SINGLEARG_OR_MULTIARG(...) \
84
_TAKE_65TH_TOKEN(__VA_ARGS__, \
85
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
86
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
87
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
88
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
89
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
90
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
91
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
92
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
93
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
94
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
95
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
96
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
97
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
98
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
99
MULTIARG, MULTIARG, MULTIARG, MULTIARG, \
100
MULTIARG, MULTIARG, MULTIARG, SINGLEARG)
101
#define _CONCAT_HELPER(a, b) a ## b
102
#define _CONCAT(a, b) _CONCAT_HELPER(a, b)
103
104
/* Implementation for `printf(fmt)` */
105
#define _PRINTF_SINGLEARG(x) \
106
flash_printf(TO_FLASH(x))
107
/* Implementation for `printf(fmt, ...)` */
108
#define _PRINTF_MULTIARG(x, ...) \
109
flash_printf(TO_FLASH(x), __VA_ARGS__)
110
/* Dispatch to _PRINTF_SINGLEARG() and _PRINTF_MULTIARG() depending on the
111
* number of arguments. Special handling for `printf(fmt)` compared to
112
* `printf(fmt, ...)` is needed because the `__VA_ARGS__` part must contain
113
* at least one argument, which in case of `printf(fmt)` is not the case. */
114
#define printf(...) \
115
_EXPAND(_CONCAT(_PRINTF_, _SINGLEARG_OR_MULTIARG(__VA_ARGS__))(__VA_ARGS__))
116
117
/* And now all other printf variants. For the v*printf() versions we do not
118
* need to differentiate, because they have always the same number of arguments
119
* (with the last being va_list). For the other printf variants, we again need
120
* to dispatch to a _SINGLEARG and a _MULTIARG version. */
121
#define vprintf(fmt, args) flash_vprintf(TO_FLASH(fmt), args)
122
123
#define _FPRINTF_SINGLEARG(stream, x) \
124
flash_fprintf(stream, TO_FLASH(x))
125
#define _FPRINTF_MULTIARG(stream, x, ...) \
126
flash_fprintf(stream, TO_FLASH(x), __VA_ARGS__)
127
#define fprintf(stream, ...) \
128
_EXPAND(_CONCAT(_FPRINTF_, _SINGLEARG_OR_MULTIARG(__VA_ARGS__))(stream, __VA_ARGS__))
129
130
#define vfprintf(stream, fmt, args) flash_vfprintf(stream, TO_FLASH(fmt), args)
131
132
#define _SNPRINTF_SINGLEARG(buf, buf_len, fmt) \
133
flash_snprintf(buf, buf_len, TO_FLASH(fmt))
134
#define _SNPRINTF_MULTIARG(buf, buf_len, fmt, ...) \
135
flash_snprintf(buf, buf_len, TO_FLASH(fmt), __VA_ARGS__)
136
#define snprintf(buf, buf_len, ...) \
137
_EXPAND(_CONCAT(_SNPRINTF_, _SINGLEARG_OR_MULTIARG(__VA_ARGS__))(buf, buf_len, __VA_ARGS__))
138
139
#define vsnprintf(buf, buf_len, fmt, args) flash_vsnprintf(buf, buf_len, TO_FLASH(fmt), args)
140
#endif
141
142
#endif
143
144
#endif
/* STDIO_H */
flash_utils.h
Utility functions, macros, and types for read-only memory.
Generated on Fri Nov 15 2024 13:54:24 by
1.9.8