VirtualBox

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

Last change on this file since 40907 was 38524, checked in by vboxsync, 13 years ago

Main/glue/ErrorInfo: more macros

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