VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTR0Common.h@ 100838

Last change on this file since 100838 was 99776, checked in by vboxsync, 20 months ago

*: Mark functions as static if not used outside of a given compilation unit. Enables the compiler to optimize inlining, reduces the symbol tables, exposes unused functions and in some rare cases exposes mismtaches between function declarations and definitions, but most importantly reduces the number of parfait reports for the extern-function-no-forward-declaration category. This should not result in any functional changes, bugref:3409 [build fix]

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.4 KB
Line 
1/* $Id: tstRTR0Common.h 99776 2023-05-12 12:26:10Z vboxsync $ */
2/** @file
3 * IPRT R0 Testcase - Common header.
4 */
5
6/*
7 * Copyright (C) 2010-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37#ifndef IPRT_INCLUDED_SRC_testcase_tstRTR0Common_h
38#define IPRT_INCLUDED_SRC_testcase_tstRTR0Common_h
39#ifndef RT_WITHOUT_PRAGMA_ONCE
40# pragma once
41#endif
42
43#include <iprt/stdarg.h>
44#include <iprt/string.h>
45#include "tstRTR0CommonReq.h"
46
47
48/*******************************************************************************
49* Global Variables *
50*******************************************************************************/
51/** Global error buffer used by macros and inline functions in this file. */
52static char g_szErr[2048];
53/** The number of errors reported in this g_szErr. */
54static uint32_t volatile g_cErrors;
55
56
57/**
58 * Service request handler prolog.
59 *
60 * Returns if the input is invalid. Initializes the return packet as well as
61 * the globals (g_szErr, g_cErrors).
62 *
63 * @param pReqHdr The request packet header.
64 */
65#define RTR0TESTR0_SRV_REQ_PROLOG_RET(pReqHdr) \
66 do \
67 { \
68 if (!RT_VALID_PTR(pReqHdr)) \
69 return VERR_INVALID_PARAMETER; \
70 \
71 PRTTSTR0REQ pReq = (PRTTSTR0REQ)(pReqHdr); \
72 size_t cchErr = pReqHdr->cbReq - sizeof(pReq->Hdr); \
73 if (cchErr < 32 || cchErr >= 0x10000) \
74 return VERR_INVALID_PARAMETER; \
75 pReq->szMsg[0] = '\0'; \
76 \
77 /* Initialize the global buffer. */ \
78 memset(&g_szErr[0], 0, sizeof(g_szErr)); \
79 ASMAtomicWriteU32(&g_cErrors, 0); \
80 } while (0)
81
82
83/**
84 * Service request handler epilog.
85 *
86 * Copies any errors or messages into the request packet.
87 *
88 * @param pReqHdr The request packet header.
89 */
90#define RTR0TESTR0_SRV_REQ_EPILOG(pReqHdr) \
91 do \
92 { \
93 PRTTSTR0REQ pReq = (PRTTSTR0REQ)(pReqHdr); \
94 size_t cbErr = pReqHdr->cbReq - sizeof(pReq->Hdr); \
95 if (g_szErr[0] && pReq->szMsg[0] != '!') \
96 RTStrCopyEx(pReq->szMsg, (cbErr), g_szErr, sizeof(g_szErr) - 1); \
97 } while (0)
98
99
100/**
101 * Implement the sanity check switch-cases of a service request handler.
102 */
103#define RTR0TESTR0_IMPLEMENT_SANITY_CASES() \
104 case RTTSTR0REQ_SANITY_OK: \
105 break; \
106 case RTTSTR0REQ_SANITY_FAILURE: \
107 RTR0TestR0Error("42failure42%4096s", ""); \
108 break
109
110/**
111 * Implements the default switch-case of a service request handler.
112 * @param uOperation The operation.
113 */
114#define RTR0TESTR0_IMPLEMENT_DEFAULT_CASE(uOperation) \
115 default: \
116 RTR0TestR0Error("Unknown test #%d", (uOperation)); \
117 break
118
119
120/**
121 * Macro for checking the return code of an API in the ring-0 testcase.
122 *
123 * Similar to RTTESTI_CHECK_RC.
124 *
125 * @param rcExpr The expression producing the return code. Only
126 * evaluated once.
127 * @param rcExpect The expected result. Evaluated multiple times.
128 */
129#define RTR0TESTR0_CHECK_RC(rcExpr, rcExpect) \
130 do { \
131 int rcCheck = (rcExpr); \
132 if (rcCheck != (rcExpect)) \
133 RTR0TestR0Error("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
134 } while (0)
135
136/**
137 * Same as RTR0TESTR0_CHECK_RC + break.
138 */
139#define RTR0TESTR0_CHECK_RC_BREAK(rcExpr, rcExpect) \
140 if (1) \
141 { \
142 int rcCheck = (rcExpr); \
143 if (rcCheck != (rcExpect)) \
144 { \
145 RTR0TestR0Error("line %u: %s: expected %Rrc, got %Rrc", __LINE__, #rcExpr, (rcExpect), rcCheck); \
146 break; \
147 } \
148 } else do { } while (0)
149
150/**
151 * Macro for checking the return code of an API in the ring-0 testcase.
152 *
153 * Similar to RTTESTI_CHECK_MSG
154 *
155 * @param expr The expression to evaluate.
156 * @param DetailsArgs Format string + arguments - in parenthesis.
157 */
158#define RTR0TESTR0_CHECK_MSG(expr, DetailsArgs) \
159 do { \
160 if (!(expr)) \
161 { \
162 RTR0TestR0Error("line %u: expression failed: %s - ", __LINE__, #expr); \
163 RTR0TestR0AppendDetails DetailsArgs; \
164 } \
165 } while (0)
166
167/**
168 * Same as RTR0TESTR0_CHECK_MSG + break.
169 */
170#define RTR0TESTR0_CHECK_MSG_BREAK(expr, DetailsArgs) \
171 if (!(expr)) \
172 { \
173 RTR0TestR0Error("line %u: expression failed: %s - ", __LINE__, #expr); \
174 RTR0TestR0AppendDetails DetailsArgs; \
175 break; \
176 } else do { } while (0)
177
178/**
179 * Same as RTR0TESTR0_CHECK_MSG + return @a rcRete.
180 */
181#define RTR0TESTR0_CHECK_MSG_RET(expr, DetailsArgs, rcRet) \
182 do { \
183 if (!(expr)) \
184 { \
185 RTR0TestR0Error("line %u: expression failed: %s - ", __LINE__, #expr); \
186 RTR0TestR0AppendDetails DetailsArgs; \
187 return (rcRet); \
188 } \
189 } while (0)
190
191/**
192 * Macro for skipping a test in the ring-0 testcase.
193 */
194#define RTR0TESTR0_SKIP() \
195 do { \
196 RTR0TestR0Skip("line %u: SKIPPED", __LINE__); \
197 } while (0)
198
199/**
200 * Same as RTR0TESTR0_SKIP + break.
201 */
202#define RTR0TESTR0_SKIP_BREAK() \
203 if (1) \
204 { \
205 RTR0TestR0Skip("line %u: SKIPPED", __LINE__); \
206 break; \
207 } else do { } while (0)
208
209
210/**
211 * Report an error.
212 */
213DECLINLINE(void) RTR0TestR0Error(const char *pszFormat, ...)
214{
215 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
216 size_t cbLeft = sizeof(g_szErr) - off;
217 if (cbLeft > 10)
218 {
219 char *psz = &g_szErr[off];
220 if (off)
221 {
222 *psz++ = '\n';
223 *psz++ = '\n';
224 cbLeft -= 2;
225 }
226 *psz++ = '!';
227 cbLeft--;
228
229 va_list va;
230 va_start(va, pszFormat);
231 RTStrPrintfV(psz, cbLeft, pszFormat, va);
232 va_end(va);
233 }
234 ASMAtomicIncU32(&g_cErrors);
235}
236
237
238/**
239 * Append error details.
240 */
241static void RTR0TestR0AppendDetails(const char *pszFormat, ...)
242{
243 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
244 va_list va;
245 va_start(va, pszFormat);
246 RTStrPrintfV(&g_szErr[off], sizeof(g_szErr) - off, pszFormat, va);
247 va_end(va);
248}
249
250
251/**
252 * Informational message.
253 */
254DECLINLINE(void) RTR0TestR0Info(const char *pszFormat, ...)
255{
256 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
257 size_t cbLeft = sizeof(g_szErr) - off;
258 if (cbLeft > 10)
259 {
260 char *psz = &g_szErr[off];
261 if (off)
262 {
263 *psz++ = '\n';
264 *psz++ = '\n';
265 cbLeft -= 2;
266 }
267 *psz++ = '?';
268 cbLeft--;
269
270 va_list va;
271 va_start(va, pszFormat);
272 RTStrPrintfV(psz, cbLeft, pszFormat, va);
273 va_end(va);
274 }
275}
276
277
278/**
279 * Report an error.
280 */
281DECLINLINE(void) RTR0TestR0Skip(const char *pszFormat, ...)
282{
283 size_t off = RTStrNLen(g_szErr, sizeof(g_szErr) - 1);
284 size_t cbLeft = sizeof(g_szErr) - off;
285 if (cbLeft > 10)
286 {
287 char *psz = &g_szErr[off];
288 if (off)
289 {
290 *psz++ = '\n';
291 *psz++ = '\n';
292 cbLeft -= 2;
293 }
294 *psz++ = '$';
295 cbLeft--;
296
297 va_list va;
298 va_start(va, pszFormat);
299 RTStrPrintfV(psz, cbLeft, pszFormat, va);
300 va_end(va);
301 }
302 ASMAtomicIncU32(&g_cErrors);
303}
304
305
306/**
307 * Checks if we have any error reports.
308 *
309 * @returns true if there are errors, false if none.
310 */
311DECLINLINE(bool) RTR0TestR0HaveErrors(void)
312{
313 return ASMAtomicUoReadU32(&g_cErrors) > 0;
314}
315
316#endif /* !IPRT_INCLUDED_SRC_testcase_tstRTR0Common_h */
317
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette