VirtualBox

source: vbox/trunk/include/VBox/com/errorprint.h@ 52225

Last change on this file since 52225 was 45125, checked in by vboxsync, 12 years ago

VBox/com/*.h: file header and block fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.1 KB
Line 
1/** @file
2 * MS COM / XPCOM Abstraction Layer - Error Reporting.
3 *
4 * Error printing macros using shared functions defined in shared glue code.
5 * Use these CHECK_* macros for efficient error checking around calling COM
6 * methods.
7 */
8
9/*
10 * Copyright (C) 2009-2011 Oracle Corporation
11 *
12 * This file is part of VirtualBox Open Source Edition (OSE), as
13 * available from http://www.virtualbox.org. This file is free software;
14 * you can redistribute it and/or modify it under the terms of the GNU
15 * General Public License (GPL) as published by the Free Software
16 * Foundation, in version 2 as it comes in the "COPYING" file of the
17 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 *
20 * The contents of this file may alternatively be used under the terms
21 * of the Common Development and Distribution License Version 1.0
22 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23 * VirtualBox OSE distribution, in which case the provisions of the
24 * CDDL are applicable instead of those of the GPL.
25 *
26 * You may elect to license modified versions of this file under the
27 * terms and conditions of either the GPL or the CDDL or both.
28 */
29
30#ifndef ___VBox_com_errorprint_h
31#define ___VBox_com_errorprint_h
32
33#include <VBox/com/ErrorInfo.h>
34
35namespace com
36{
37
38// shared prototypes; these are defined in shared glue code and are
39// compiled only once for all front-ends
40void GluePrintErrorInfo(const com::ErrorInfo &info);
41void GluePrintErrorContext(const char *pcszContext, const char *pcszSourceFile, uint32_t ulLine);
42void GluePrintRCMessage(HRESULT rc);
43void GlueHandleComError(ComPtr<IUnknown> iface,
44 const char *pcszContext,
45 HRESULT rc,
46 const char *pcszSourceFile,
47 uint32_t ulLine);
48void GlueHandleComErrorProgress(ComPtr<IProgress> progress,
49 const char *pcszContext,
50 HRESULT rc,
51 const char *pcszSourceFile,
52 uint32_t ulLine);
53
54/**
55 * Calls the given method of the given interface and then checks if the return
56 * value (COM result code) indicates a failure. If so, prints the failed
57 * function/line/file, the description of the result code and attempts to
58 * query the extended error information on the current thread (using
59 * com::ErrorInfo) if the interface reports that it supports error information.
60 *
61 * Used by command line tools or for debugging and assumes the |HRESULT rc|
62 * variable is accessible for assigning in the current scope.
63 */
64#define CHECK_ERROR(iface, method) \
65 do { \
66 rc = iface->method; \
67 if (FAILED(rc)) \
68 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
69 } while (0)
70
71/**
72 * Same as CHECK_ERROR except that it also executes the statement |stmt| on
73 * failure.
74 */
75#define CHECK_ERROR_STMT(iface, method, stmt) \
76 do { \
77 rc = iface->method; \
78 if (FAILED(rc)) \
79 { \
80 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
81 stmt; \
82 } \
83 } while (0)
84
85/**
86 * Same as CHECK_ERROR_STMT except that it uses an internal variable |hrcCheck|
87 * for holding the result.
88 */
89#define CHECK_ERROR2_STMT(iface, method, stmt) \
90 do { \
91 HRESULT hrcCheck = iface->method; \
92 if (FAILED(hrcCheck)) \
93 { \
94 com::GlueHandleComError(iface, #method, hrcCheck, __FILE__, __LINE__); \
95 stmt; \
96 } \
97 } while (0)
98
99
100/**
101 * Does the same as CHECK_ERROR(), but executes the |break| statement on
102 * failure.
103 */
104#ifdef __GNUC__
105# define CHECK_ERROR_BREAK(iface, method) \
106 __extension__ \
107 ({ \
108 rc = iface->method; \
109 if (FAILED(rc)) \
110 { \
111 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
112 break; \
113 } \
114 })
115#else
116# define CHECK_ERROR_BREAK(iface, method) \
117 if (1) \
118 { \
119 rc = iface->method; \
120 if (FAILED(rc)) \
121 { \
122 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
123 break; \
124 } \
125 } \
126 else do {} while (0)
127#endif
128
129/**
130 * Does the same as CHECK_ERROR(), but executes the |return ret| statement on
131 * failure.
132 */
133#define CHECK_ERROR_RET(iface, method, ret) \
134 do { \
135 rc = iface->method; \
136 if (FAILED(rc)) \
137 { \
138 com::GlueHandleComError(iface, #method, rc, __FILE__, __LINE__); \
139 return (ret); \
140 } \
141 } while (0)
142
143/**
144 * Does the same as CHECK_ERROR(), but returns @a ret on failure.
145 *
146 * Unlike CHECK_ERROR and CHECK_ERROR_RET, this macro does not presuppose a
147 * |rc| variable but instead employs a local variable |hrcCheck| in its own
148 * scope. This |hrcCheck| variable can be referenced by the @a rcRet
149 * parameter.
150 *
151 * @param iface The interface pointer (can be a smart pointer object).
152 * @param method The method to invoke together with the parameters.
153 * @param rcRet What to return on failure. Use |hrcCheck| to return
154 * the status code of the method call.
155 */
156#define CHECK_ERROR2_RET(iface, method, rcRet) \
157 do { \
158 HRESULT hrcCheck = iface->method; \
159 if (FAILED(hrcCheck)) \
160 { \
161 com::GlueHandleComError(iface, #method, hrcCheck, __FILE__, __LINE__); \
162 return (rcRet); \
163 } \
164 } while (0)
165
166
167/**
168 * Check the progress object for an error and if there is one print out the
169 * extended error information.
170 */
171#define CHECK_PROGRESS_ERROR(progress, msg) \
172 do { \
173 LONG iRc; \
174 rc = progress->COMGETTER(ResultCode)(&iRc); \
175 if (FAILED(iRc)) \
176 { \
177 rc = iRc; \
178 RTMsgError msg; \
179 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
180 } \
181 } while (0)
182
183/**
184 * Does the same as CHECK_PROGRESS_ERROR(), but executes the |break| statement
185 * on failure.
186 */
187#ifdef __GNUC__
188# define CHECK_PROGRESS_ERROR_BREAK(progress, msg) \
189 __extension__ \
190 ({ \
191 LONG iRc; \
192 rc = progress->COMGETTER(ResultCode)(&iRc); \
193 if (FAILED(iRc)) \
194 { \
195 rc = iRc; \
196 RTMsgError msg; \
197 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
198 break; \
199 } \
200 })
201#else
202# define CHECK_PROGRESS_ERROR_BREAK(progress, msg) \
203 if (1) \
204 { \
205 LONG iRc; \
206 rc = progress->COMGETTER(ResultCode)(&iRc); \
207 if (FAILED(iRc)) \
208 { \
209 rc = iRc; \
210 RTMsgError msg; \
211 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
212 break; \
213 } \
214 } \
215 else do {} while (0)
216#endif
217
218/**
219 * Does the same as CHECK_PROGRESS_ERROR(), but executes the |return ret|
220 * statement on failure.
221 */
222#define CHECK_PROGRESS_ERROR_RET(progress, msg, ret) \
223 do { \
224 LONG iRc; \
225 progress->COMGETTER(ResultCode)(&iRc); \
226 if (FAILED(iRc)) \
227 { \
228 RTMsgError msg; \
229 com::GlueHandleComErrorProgress(progress, __PRETTY_FUNCTION__, iRc, __FILE__, __LINE__); \
230 return (ret); \
231 } \
232 } while (0)
233
234/**
235 * Asserts the given expression is true. When the expression is false, prints
236 * a line containing the failed function/line/file; otherwise does nothing.
237 */
238#define ASSERT(expr) \
239 do { \
240 if (!(expr)) \
241 { \
242 RTPrintf ("[!] ASSERTION FAILED at line %d: %s\n", __LINE__, #expr); \
243 Log (("[!] ASSERTION FAILED at line %d: %s\n", __LINE__, #expr)); \
244 } \
245 } while (0)
246
247#endif
248
249/**
250 * Does the same as ASSERT(), but executes the |return ret| statement if the
251 * expression to assert is false;
252 */
253#define ASSERT_RET(expr, ret) \
254 do { ASSERT(expr); if (!(expr)) return (ret); } while (0)
255
256/**
257 * Does the same as ASSERT(), but executes the |break| statement if the
258 * expression to assert is false;
259 */
260#define ASSERT_BREAK(expr, ret) \
261 if (1) { ASSERT(expr); if (!(expr)) break; } else do {} while (0)
262
263} /* namespace com */
264
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