diag-trace 4.2.1
The µOS++ Tracing Infrastructure
Loading...
Searching...
No Matches
trace.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ project (https://micro-os-plus.github.io/).
3 * Copyright (c) 2015-2025 Liviu Ionescu. All rights reserved.
4 *
5 * Permission to use, copy, modify, and/or distribute this software
6 * for any purpose is hereby granted, under the terms of the MIT license.
7 *
8 * If a copy of the license was not distributed with this file, it can
9 * be obtained from https://opensource.org/licenses/mit.
10 */
11
12// ----------------------------------------------------------------------------
13
14#if defined(MICRO_OS_PLUS_INCLUDE_CONFIG_H)
15#include <micro-os-plus/config.h>
16#endif // MICRO_OS_PLUS_INCLUDE_CONFIG_H
17
18#if defined(MICRO_OS_PLUS_TRACE) || defined(MICRO_OS_PLUS_TRACE_TESTING)
19
20// ----------------------------------------------------------------------------
21
23
24#include <cstdarg>
25#include <cstdio>
26#include <cstring>
27
28#ifndef MICRO_OS_PLUS_INTEGER_TRACE_PRINTF_BUFFER_ARRAY_SIZE
29#define MICRO_OS_PLUS_INTEGER_TRACE_PRINTF_BUFFER_ARRAY_SIZE (200)
30#endif
31
32// ----------------------------------------------------------------------------
33
34#if defined(__clang__)
35#pragma clang diagnostic ignored "-Wunknown-warning-option"
36#pragma clang diagnostic ignored "-Wc++98-c++11-c++14-compat"
37#endif
38
39// For separation, use a separate naming space while testing.
40namespace micro_os_plus::MICRO_OS_PLUS_TRACE_NAME_TESTING(trace)
41
42{
43 // --------------------------------------------------------------------------
44
45 int
46 printf (const char* format, ...)
47 {
48 std::va_list arguments;
49 va_start (arguments, format);
50
51#pragma GCC diagnostic push
52#if defined(__clang__)
53#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
54#endif
55 int ret = vprintf (format, arguments);
56#pragma GCC diagnostic pop
57
58 va_end (arguments);
59 return ret;
60 }
61
62 int
63 vprintf (const char* format, std::va_list arguments)
64 {
65 // Caution: allocated on the stack!
67
68 // TODO: possibly rewrite it to no longer use newlib,
69 // (although the nano version is no longer very heavy).
70
71 // Print to the local buffer
72#pragma GCC diagnostic push
73#pragma GCC diagnostic ignored "-Wformat-nonliteral"
74#if defined(__clang__)
75#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
76#endif
77 ssize_t ret = ::vsnprintf (buf, sizeof (buf), format, arguments);
78#pragma GCC diagnostic pop
79 if (ret > 0)
80 {
81 // Transfer the buffer to the device.
82 ret = write (buf, static_cast<size_t> (ret));
83 }
84#pragma GCC diagnostic push
85#if defined(__GNUC__) && !defined(__clang__)
86#pragma GCC diagnostic ignored "-Wuseless-cast"
87#endif
88 // Cast required on 64-bit.
89 return static_cast<int> (ret);
90#pragma GCC diagnostic pop
91 }
92
93 int
94 puts (const char* s)
95 {
96#pragma GCC diagnostic push
97#if defined(__clang__)
98#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
99#endif
100 ssize_t ret = write (s, strlen (s));
101#pragma GCC diagnostic pop
102 if (ret >= 0)
103 {
104 ret = write ("\n", 1); // Add a line terminator
105 }
106 if (ret > 0)
107 {
108#pragma GCC diagnostic push
109#if defined(__GNUC__) && !defined(__clang__)
110#pragma GCC diagnostic ignored "-Wuseless-cast"
111#endif
112 // Cast required on 64-bit.
113 return static_cast<int> (ret);
114#pragma GCC diagnostic pop
115 }
116 else
117 {
118 return EOF;
119 }
120 }
121
122 int
123 putchar (int c)
124 {
125 ssize_t ret = write (reinterpret_cast<const char*> (&c), 1);
126 if (ret > 0)
127 {
128 return c;
129 }
130 else
131 {
132 return EOF;
133 }
134 }
135
141#pragma GCC diagnostic push
142#if defined(__clang__)
143#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
144#endif
145 void
146 dump_args (int argc, char* argv[], const char* name)
147 {
148 printf ("%s(argc=%d, argv=[", name, argc);
149 for (int i = 0; i < argc; ++i)
150 {
151 if (i != 0)
152 {
153 printf (", ");
154 }
155 printf ("\"%s\"", argv[i]);
156 }
157 printf ("])\n");
158 }
159#pragma GCC diagnostic pop
160
161 // --------------------------------------------------------------------------
162} // namespace micro_os_plus::trace
163
164// ----------------------------------------------------------------------------
165
166using namespace micro_os_plus;
167
168// These cannot be aliased, since they usually are defined
169// in a different translation unit.
170
171void
176
177ssize_t
179 const void* buf, std::size_t nbyte)
180{
181 return MICRO_OS_PLUS_TRACE_NAME_TESTING (trace)::write (buf, nbyte);
182}
183
184void
189
190// ----------------------------------------------------------------------------
191
192// For non-embedded platforms, to remain compatible with OS X which does
193// not support aliases, redefine the C functions to call the C++ versions.
194
195int
197 const char* format, ...)
198{
199 std::va_list arguments;
200 va_start (arguments, format);
201
202#pragma GCC diagnostic push
203#if defined(__clang__)
204#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
205#endif
206 int ret
207 = MICRO_OS_PLUS_TRACE_NAME_TESTING (trace)::vprintf (format, arguments);
208#pragma GCC diagnostic pop
209
210 va_end (arguments);
211 return ret;
212}
213
214int
216 const char* format, va_list arguments)
217{
218#pragma GCC diagnostic push
219#if defined(__clang__)
220#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
221#endif
222 return MICRO_OS_PLUS_TRACE_NAME_TESTING (trace)::vprintf (format, arguments);
223#pragma GCC diagnostic pop
224}
225
226int
228{
229#pragma GCC diagnostic push
230#if defined(__clang__)
231#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
232#endif
233 return MICRO_OS_PLUS_TRACE_NAME_TESTING (trace)::puts (s);
234#pragma GCC diagnostic pop
235}
236
237int
239{
240#pragma GCC diagnostic push
241#if defined(__clang__)
242#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
243#endif
244 return MICRO_OS_PLUS_TRACE_NAME_TESTING (trace)::putchar (c);
245#pragma GCC diagnostic pop
246}
247
248void
250 char* argv[])
251{
252#pragma GCC diagnostic push
253#if defined(__clang__)
254#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
255#endif
256 MICRO_OS_PLUS_TRACE_NAME_TESTING (trace)::dump_args (argc, argv);
257#pragma GCC diagnostic pop
258}
259
260// ----------------------------------------------------------------------------
261
262#endif // defined(MICRO_OS_PLUS_TRACE)
263
264// ----------------------------------------------------------------------------
void micro_os_plus_trace_dump_args(int argc, char *argv[])
Write the argv[] array to the trace output channel.
Definition trace.cpp:249
void micro_os_plus_trace_initialize(void)
Initialize the trace output channel.
Definition trace.cpp:172
ssize_t micro_os_plus_trace_write(const void *buf, size_t nbyte)
Write the given number of bytes to the trace output channel.
void micro_os_plus_trace_flush(void)
Flush the trace output channel.
Definition trace.cpp:185
int micro_os_plus_trace_printf(const char *format,...)
Write a formatted string to the trace output channel.
Definition trace.cpp:196
int micro_os_plus_trace_puts(const char *s)
Write the string and a line terminator to the trace output channel.
Definition trace.cpp:227
int micro_os_plus_trace_vprintf(const char *format, va_list arguments)
Write a formatted variable arguments list to the trace output channel.
Definition trace.cpp:215
int micro_os_plus_trace_putchar(int c)
Write the single character to the trace output channel.
Definition trace.cpp:238
void dump_args(int argc, char *argv[], const char *name="main")
Send the argv[] array to the trace output channel.
Definition trace.cpp:146
ssize_t write(const void *buf, std::size_t nbyte)
Write the given number of bytes to the trace output channel.
int printf(const char *format,...)
Write a formatted string to the trace output channel.
Definition trace.cpp:46
int putchar(int c)
Write the single character to the trace output channel.
Definition trace.cpp:123
int puts(const char *s="")
Write the string and a line terminator to the trace output channel.
Definition trace.cpp:94
int vprintf(const char *format, std::va_list arguments)
Write a formatted variable arguments list to the trace output channel.
Definition trace.cpp:63
Tracing support namespace.
Definition trace.h:95
#define MICRO_OS_PLUS_INTEGER_TRACE_PRINTF_BUFFER_ARRAY_SIZE
Definition trace.cpp:29
#define MICRO_OS_PLUS_TRACE_NAME_TESTING(name)
Definition trace.h:51