Line | Count | Source |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /* |
14 | | * Purpose: Provides error handling in the form of a stack. The |
15 | | * FUNC_ENTER() macro clears the error stack whenever an API |
16 | | * function is entered. When an error is detected, an entry is |
17 | | * pushed onto the stack. As the functions unwind additional |
18 | | * entries are pushed onto the stack. The API function will |
19 | | * return some indication that an error occurred and the |
20 | | * application can print the error stack. |
21 | | * |
22 | | * Certain API functions in the H5E package (such as H5Eprint2()) |
23 | | * do not clear the error stack. Otherwise, any function which |
24 | | * doesn't have an underscore immediately after the package name |
25 | | * will clear the error stack. For instance, H5Fopen() clears |
26 | | * the error stack while H5F_open() does not. |
27 | | * |
28 | | * An error stack has a fixed maximum size. If this size is |
29 | | * exceeded then the stack will be truncated and only the |
30 | | * inner-most functions will have entries on the stack. This is |
31 | | * expected to be a rare condition. |
32 | | * |
33 | | * Each thread has its own error stack, but since |
34 | | * multi-threading has not been added to the library yet, this |
35 | | * package maintains a single error stack. The error stack is |
36 | | * statically allocated to reduce the complexity of handling |
37 | | * errors within the H5E package. |
38 | | * |
39 | | */ |
40 | | |
41 | | /****************/ |
42 | | /* Module Setup */ |
43 | | /****************/ |
44 | | |
45 | | #include "H5Emodule.h" /* This source code file is part of the H5E module */ |
46 | | |
47 | | /***********/ |
48 | | /* Headers */ |
49 | | /***********/ |
50 | | #include "H5private.h" /* Generic Functions */ |
51 | | #include "H5Epkg.h" /* Error handling */ |
52 | | #include "H5FLprivate.h" /* Free lists */ |
53 | | #include "H5Iprivate.h" /* IDs */ |
54 | | #include "H5MMprivate.h" /* Memory management */ |
55 | | |
56 | | /****************/ |
57 | | /* Local Macros */ |
58 | | /****************/ |
59 | | |
60 | | /******************/ |
61 | | /* Local Typedefs */ |
62 | | /******************/ |
63 | | |
64 | | /********************/ |
65 | | /* Package Typedefs */ |
66 | | /********************/ |
67 | | |
68 | | /********************/ |
69 | | /* Local Prototypes */ |
70 | | /********************/ |
71 | | |
72 | | /*********************/ |
73 | | /* Package Variables */ |
74 | | /*********************/ |
75 | | |
76 | | /* Package initialization variable */ |
77 | | bool H5_PKG_INIT_VAR = false; |
78 | | |
79 | | /* Declare extern the free list to manage the H5E_stack_t struct */ |
80 | | H5FL_EXTERN(H5E_stack_t); |
81 | | |
82 | | /*****************************/ |
83 | | /* Library Private Variables */ |
84 | | /*****************************/ |
85 | | |
86 | | /*******************/ |
87 | | /* Local Variables */ |
88 | | /*******************/ |
89 | | |
90 | | /*------------------------------------------------------------------------- |
91 | | * Function: H5Eregister_class |
92 | | * |
93 | | * Purpose: Registers an error class. |
94 | | * |
95 | | * Return: Success: An ID for the error class |
96 | | * Failure: H5I_INVALID_HID |
97 | | * |
98 | | *------------------------------------------------------------------------- |
99 | | */ |
100 | | hid_t |
101 | | H5Eregister_class(const char *cls_name, const char *lib_name, const char *version) |
102 | 0 | { |
103 | 0 | H5E_cls_t *cls; /* Pointer to error class */ |
104 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
105 | |
|
106 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
107 | | |
108 | | /* Check arguments */ |
109 | 0 | if (cls_name == NULL || lib_name == NULL || version == NULL) |
110 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "invalid string"); |
111 | | |
112 | | /* Create the new error class object */ |
113 | 0 | if (NULL == (cls = H5E__register_class(cls_name, lib_name, version))) |
114 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, H5I_INVALID_HID, "can't create error class"); |
115 | | |
116 | | /* Register the new error class to get an ID for it */ |
117 | 0 | if ((ret_value = H5I_register(H5I_ERROR_CLASS, cls, true)) < 0) |
118 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register error class"); |
119 | | |
120 | 0 | done: |
121 | 0 | FUNC_LEAVE_API(ret_value) |
122 | 0 | } /* end H5Eregister_class() */ |
123 | | |
124 | | /*------------------------------------------------------------------------- |
125 | | * Function: H5Eunregister_class |
126 | | * |
127 | | * Purpose: Closes an error class. |
128 | | * |
129 | | * Return: Non-negative value on success/Negative on failure |
130 | | * |
131 | | *------------------------------------------------------------------------- |
132 | | */ |
133 | | herr_t |
134 | | H5Eunregister_class(hid_t class_id) |
135 | 0 | { |
136 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
137 | |
|
138 | 0 | FUNC_ENTER_API(FAIL) |
139 | | |
140 | | /* Check arguments */ |
141 | 0 | if (H5I_ERROR_CLASS != H5I_get_type(class_id)) |
142 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error class"); |
143 | | |
144 | | /* |
145 | | * Decrement the counter on the dataset. It will be freed if the count |
146 | | * reaches zero. |
147 | | */ |
148 | 0 | if (H5I_dec_app_ref(class_id) < 0) |
149 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error class"); |
150 | | |
151 | 0 | done: |
152 | 0 | FUNC_LEAVE_API(ret_value) |
153 | 0 | } /* end H5Eunregister_class() */ |
154 | | |
155 | | /*------------------------------------------------------------------------- |
156 | | * Function: H5Eget_class_name |
157 | | * |
158 | | * Purpose: Retrieves error class name. |
159 | | * |
160 | | * Return: Success: Name length (zero means no name) |
161 | | * Failure: -1 |
162 | | * |
163 | | *------------------------------------------------------------------------- |
164 | | */ |
165 | | ssize_t |
166 | | H5Eget_class_name(hid_t class_id, char *name /*out*/, size_t size) |
167 | 0 | { |
168 | 0 | H5E_cls_t *cls; /* Pointer to error class */ |
169 | 0 | ssize_t ret_value = -1; /* Return value */ |
170 | |
|
171 | 0 | FUNC_ENTER_API((-1)) |
172 | | |
173 | | /* Get the error class */ |
174 | 0 | if (NULL == (cls = (H5E_cls_t *)H5I_object_verify(class_id, H5I_ERROR_CLASS))) |
175 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a error class ID"); |
176 | | |
177 | | /* Retrieve the class name */ |
178 | 0 | if ((ret_value = H5E__get_class_name(cls, name, size)) < 0) |
179 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get error class name"); |
180 | | |
181 | 0 | done: |
182 | 0 | FUNC_LEAVE_API(ret_value) |
183 | 0 | } /* end H5Eget_class_name() */ |
184 | | |
185 | | /*------------------------------------------------------------------------- |
186 | | * Function: H5Eclose_msg |
187 | | * |
188 | | * Purpose: Closes a major or minor error. |
189 | | * |
190 | | * Return: SUCCEED/FAIL |
191 | | * |
192 | | *------------------------------------------------------------------------- |
193 | | */ |
194 | | herr_t |
195 | | H5Eclose_msg(hid_t err_id) |
196 | 0 | { |
197 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
198 | |
|
199 | 0 | FUNC_ENTER_API(FAIL) |
200 | | |
201 | | /* Check arguments */ |
202 | 0 | if (H5I_ERROR_MSG != H5I_get_type(err_id)) |
203 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error class"); |
204 | | |
205 | | /* Decrement the counter. It will be freed if the count reaches zero. */ |
206 | 0 | if (H5I_dec_app_ref(err_id) < 0) |
207 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error message"); |
208 | | |
209 | 0 | done: |
210 | 0 | FUNC_LEAVE_API(ret_value) |
211 | 0 | } /* end H5Eclose_msg() */ |
212 | | |
213 | | /*------------------------------------------------------------------------- |
214 | | * Function: H5Ecreate_msg |
215 | | * |
216 | | * Purpose: Creates a major or minor error, returns an ID. |
217 | | * |
218 | | * Return: Success: An error ID |
219 | | * Failure: H5I_INVALID_HID |
220 | | * |
221 | | *------------------------------------------------------------------------- |
222 | | */ |
223 | | hid_t |
224 | | H5Ecreate_msg(hid_t class_id, H5E_type_t msg_type, const char *msg_str) |
225 | 0 | { |
226 | 0 | H5E_cls_t *cls; /* Pointer to error class */ |
227 | 0 | H5E_msg_t *msg; /* Pointer to new error message */ |
228 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
229 | |
|
230 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
231 | | |
232 | | /* Check arguments */ |
233 | 0 | if (msg_type != H5E_MAJOR && msg_type != H5E_MINOR) |
234 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "not a valid message type"); |
235 | 0 | if (msg_str == NULL) |
236 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5I_INVALID_HID, "message is NULL"); |
237 | | |
238 | | /* Get the error class */ |
239 | 0 | if (NULL == (cls = (H5E_cls_t *)H5I_object_verify(class_id, H5I_ERROR_CLASS))) |
240 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5I_INVALID_HID, "not an error class ID"); |
241 | | |
242 | | /* Create the new error message object */ |
243 | 0 | if (NULL == (msg = H5E__create_msg(cls, msg_type, msg_str))) |
244 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, H5I_INVALID_HID, "can't create error message"); |
245 | | |
246 | | /* Register the new error class to get an ID for it */ |
247 | 0 | if ((ret_value = H5I_register(H5I_ERROR_MSG, msg, true)) < 0) |
248 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't register error message"); |
249 | | |
250 | 0 | done: |
251 | 0 | FUNC_LEAVE_API(ret_value) |
252 | 0 | } /* end H5Ecreate_msg() */ |
253 | | |
254 | | /*------------------------------------------------------------------------- |
255 | | * Function: H5Eget_msg |
256 | | * |
257 | | * Purpose: Retrieves an error message. |
258 | | * |
259 | | * Return: Success: Message length (zero means no message) |
260 | | * Failure: -1 |
261 | | * |
262 | | *------------------------------------------------------------------------- |
263 | | */ |
264 | | ssize_t |
265 | | H5Eget_msg(hid_t msg_id, H5E_type_t *type /*out*/, char *msg_str /*out*/, size_t size) |
266 | 0 | { |
267 | 0 | H5E_msg_t *msg; /* Pointer to error message */ |
268 | 0 | ssize_t ret_value = -1; /* Return value */ |
269 | |
|
270 | 0 | FUNC_ENTER_API_NOCLEAR((-1)) |
271 | | |
272 | | /* Get the message object */ |
273 | 0 | if (NULL == (msg = (H5E_msg_t *)H5I_object_verify(msg_id, H5I_ERROR_MSG))) |
274 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not a error message ID"); |
275 | | |
276 | | /* Get the message's text */ |
277 | 0 | if ((ret_value = H5E__get_msg(msg, type, msg_str, size)) < 0) |
278 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get error message text"); |
279 | | |
280 | 0 | done: |
281 | 0 | FUNC_LEAVE_API(ret_value) |
282 | 0 | } /* end H5Eget_msg() */ |
283 | | |
284 | | /*------------------------------------------------------------------------- |
285 | | * Function: H5Ecreate_stack |
286 | | * |
287 | | * Purpose: Creates a new, empty, error stack. |
288 | | * |
289 | | * Return: Success: An error stack ID |
290 | | * Failure: H5I_INVALID_HID |
291 | | * |
292 | | *------------------------------------------------------------------------- |
293 | | */ |
294 | | hid_t |
295 | | H5Ecreate_stack(void) |
296 | 0 | { |
297 | 0 | H5E_stack_t *stk; /* Error stack */ |
298 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
299 | |
|
300 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
301 | | |
302 | | /* Allocate a new error stack */ |
303 | 0 | if (NULL == (stk = H5FL_CALLOC(H5E_stack_t))) |
304 | 0 | HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, H5I_INVALID_HID, "memory allocation failed"); |
305 | | |
306 | | /* Set the "automatic" error reporting info to the library default */ |
307 | 0 | H5E__set_default_auto(stk); |
308 | | |
309 | | /* Register the stack */ |
310 | 0 | if ((ret_value = H5I_register(H5I_ERROR_STACK, stk, true)) < 0) |
311 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't create error stack"); |
312 | | |
313 | 0 | done: |
314 | 0 | FUNC_LEAVE_API(ret_value) |
315 | 0 | } /* end H5Ecreate_stack() */ |
316 | | |
317 | | /*------------------------------------------------------------------------- |
318 | | * Function: H5Eget_current_stack |
319 | | * |
320 | | * Purpose: Registers current error stack, returns object handle for it, |
321 | | * clears it. |
322 | | * |
323 | | * Return: Success: An error stack ID |
324 | | * Failure: H5I_INVALID_HID |
325 | | * |
326 | | *------------------------------------------------------------------------- |
327 | | */ |
328 | | hid_t |
329 | | H5Eget_current_stack(void) |
330 | 0 | { |
331 | 0 | H5E_stack_t *stk; /* Error stack */ |
332 | 0 | hid_t ret_value = H5I_INVALID_HID; /* Return value */ |
333 | | |
334 | | /* Don't clear the error stack! :-) */ |
335 | 0 | FUNC_ENTER_API_NOCLEAR(H5I_INVALID_HID) |
336 | | |
337 | | /* Get the current stack */ |
338 | 0 | if (NULL == (stk = H5E__get_current_stack())) |
339 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTCREATE, H5I_INVALID_HID, "can't create error stack"); |
340 | | |
341 | | /* Register the stack */ |
342 | 0 | if ((ret_value = H5I_register(H5I_ERROR_STACK, stk, true)) < 0) |
343 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, H5I_INVALID_HID, "can't create error stack"); |
344 | | |
345 | 0 | done: |
346 | 0 | FUNC_LEAVE_API(ret_value) |
347 | 0 | } /* end H5Eget_current_stack() */ |
348 | | |
349 | | /*------------------------------------------------------------------------- |
350 | | * Function: H5Eset_current_stack |
351 | | * |
352 | | * Purpose: Replaces current stack with specified stack. This closes the |
353 | | * stack ID also. |
354 | | * |
355 | | * Return: Non-negative value on success/Negative on failure |
356 | | * |
357 | | *------------------------------------------------------------------------- |
358 | | */ |
359 | | herr_t |
360 | | H5Eset_current_stack(hid_t err_stack) |
361 | 0 | { |
362 | 0 | H5E_stack_t *estack; |
363 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
364 | |
|
365 | 0 | FUNC_ENTER_API(FAIL) |
366 | |
|
367 | 0 | if (err_stack != H5E_DEFAULT) { |
368 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK))) |
369 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
370 | | |
371 | | /* Set the current error stack */ |
372 | 0 | if (H5E__set_current_stack(estack) < 0) |
373 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "unable to set error stack"); |
374 | | |
375 | | /* |
376 | | * Decrement the counter on the error stack. It will be freed if the count |
377 | | * reaches zero. |
378 | | */ |
379 | 0 | if (H5I_dec_app_ref(err_stack) < 0) |
380 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error stack"); |
381 | 0 | } /* end if */ |
382 | | |
383 | 0 | done: |
384 | 0 | FUNC_LEAVE_API(ret_value) |
385 | 0 | } /* end H5Eset_current_stack() */ |
386 | | |
387 | | /*------------------------------------------------------------------------- |
388 | | * Function: H5Eclose_stack |
389 | | * |
390 | | * Purpose: Closes an error stack. |
391 | | * |
392 | | * Return: Non-negative value on success/Negative on failure |
393 | | * |
394 | | *------------------------------------------------------------------------- |
395 | | */ |
396 | | herr_t |
397 | | H5Eclose_stack(hid_t stack_id) |
398 | 0 | { |
399 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
400 | |
|
401 | 0 | FUNC_ENTER_API(FAIL) |
402 | |
|
403 | 0 | if (H5E_DEFAULT != stack_id) { |
404 | | /* Check arguments */ |
405 | 0 | if (H5I_ERROR_STACK != H5I_get_type(stack_id)) |
406 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
407 | | |
408 | | /* |
409 | | * Decrement the counter on the error stack. It will be freed if the count |
410 | | * reaches zero. |
411 | | */ |
412 | 0 | if (H5I_dec_app_ref(stack_id) < 0) |
413 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on error stack"); |
414 | 0 | } /* end if */ |
415 | | |
416 | 0 | done: |
417 | 0 | FUNC_LEAVE_API(ret_value) |
418 | 0 | } /* end H5Eclose_stack() */ |
419 | | |
420 | | /*------------------------------------------------------------------------- |
421 | | * Function: H5Eget_num |
422 | | * |
423 | | * Purpose: Retrieves the number of error messages. |
424 | | * |
425 | | * Return: Success: The number of errors |
426 | | * Failure: -1 |
427 | | * |
428 | | *------------------------------------------------------------------------- |
429 | | */ |
430 | | ssize_t |
431 | | H5Eget_num(hid_t error_stack_id) |
432 | 0 | { |
433 | 0 | H5E_stack_t *estack; /* Error stack to operate on */ |
434 | 0 | ssize_t ret_value; /* Return value */ |
435 | | |
436 | | /* Don't clear the error stack! :-) */ |
437 | 0 | FUNC_ENTER_API_NOCLEAR((-1)) |
438 | | |
439 | | /* Need to check for errors */ |
440 | 0 | if (error_stack_id == H5E_DEFAULT) { |
441 | 0 | if (NULL == (estack = H5E__get_my_stack())) |
442 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get current error stack"); |
443 | 0 | } /* end if */ |
444 | 0 | else { |
445 | | /* Only clear the error stack if it's not the default stack */ |
446 | 0 | H5E_clear_stack(); |
447 | | |
448 | | /* Get the error stack to operate on */ |
449 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(error_stack_id, H5I_ERROR_STACK))) |
450 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, (-1), "not an error stack ID"); |
451 | 0 | } /* end else */ |
452 | | |
453 | | /* Get the number of errors on stack */ |
454 | 0 | if ((ret_value = H5E__get_num(estack)) < 0) |
455 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, (-1), "can't get number of errors"); |
456 | | |
457 | 0 | done: |
458 | 0 | FUNC_LEAVE_API(ret_value) |
459 | 0 | } /* end H5Eget_num() */ |
460 | | |
461 | | /*------------------------------------------------------------------------- |
462 | | * Function: H5Epop |
463 | | * |
464 | | * Purpose: Deletes some error messages from the top of error stack. |
465 | | * |
466 | | * Return: Non-negative value on success/Negative on failure |
467 | | * |
468 | | *------------------------------------------------------------------------- |
469 | | */ |
470 | | herr_t |
471 | | H5Epop(hid_t err_stack, size_t count) |
472 | 0 | { |
473 | 0 | H5E_stack_t *estack; |
474 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
475 | | |
476 | | /* Don't clear the error stack! :-) */ |
477 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
478 | | |
479 | | /* Need to check for errors */ |
480 | 0 | if (err_stack == H5E_DEFAULT) { |
481 | 0 | if (NULL == (estack = H5E__get_my_stack())) |
482 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
483 | 0 | } /* end if */ |
484 | 0 | else { |
485 | | /* Only clear the error stack if it's not the default stack */ |
486 | 0 | H5E_clear_stack(); |
487 | | |
488 | | /* Get the error stack to operate on */ |
489 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK))) |
490 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
491 | 0 | } /* end else */ |
492 | | |
493 | | /* Range limit the number of errors to pop off stack */ |
494 | 0 | if (count > estack->nused) |
495 | 0 | count = estack->nused; |
496 | | |
497 | | /* Pop the errors off the stack */ |
498 | 0 | if (H5E__pop(estack, count) < 0) |
499 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTRELEASE, FAIL, "can't pop errors from stack"); |
500 | | |
501 | 0 | done: |
502 | 0 | FUNC_LEAVE_API(ret_value) |
503 | 0 | } /* end H5Epop() */ |
504 | | |
505 | | /*------------------------------------------------------------------------- |
506 | | * Function: H5Epush2 |
507 | | * |
508 | | * Purpose: Pushes a new error record onto error stack for the current |
509 | | * thread. The error has major and minor IDs MAJ_ID and |
510 | | * MIN_ID, the name of a function where the error was detected, |
511 | | * the name of the file where the error was detected, the |
512 | | * line within that file, and an error description string. The |
513 | | * function name, file name, and error description strings must |
514 | | * be statically allocated. |
515 | | * |
516 | | * Return: Non-negative on success/Negative on failure |
517 | | * |
518 | | * Notes: Basically a new public API wrapper around the H5E__push_stack |
519 | | * function. |
520 | | * |
521 | | *------------------------------------------------------------------------- |
522 | | */ |
523 | | H5_ATTR_FORMAT(printf, 8, 9) |
524 | | herr_t |
525 | | H5Epush2(hid_t err_stack, const char *file, const char *func, unsigned line, hid_t cls_id, hid_t maj_id, |
526 | | hid_t min_id, const char *fmt, ...) |
527 | 0 | { |
528 | 0 | H5E_stack_t *estack; /* Pointer to error stack to modify */ |
529 | 0 | va_list ap; /* Varargs info */ |
530 | 0 | bool va_started = false; /* Whether the variable argument list is open */ |
531 | 0 | const char *tmp_file; /* Copy of the file name */ |
532 | 0 | const char *tmp_func; /* Copy of the function name */ |
533 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
534 | | |
535 | | /* Don't clear the error stack! :-) */ |
536 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
537 | | |
538 | | /* Check for 'default' error stack */ |
539 | 0 | if (err_stack == H5E_DEFAULT) { |
540 | 0 | if (NULL == (estack = H5E__get_my_stack())) |
541 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get the default error stack"); |
542 | 0 | } |
543 | 0 | else { |
544 | | /* Only clear the error stack if it's not the default stack */ |
545 | 0 | H5E_clear_stack(); |
546 | | |
547 | | /* Get the error stack to operate on */ |
548 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK))) |
549 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
550 | 0 | } /* end else */ |
551 | | |
552 | | /* Check if error reporting is paused for this stack */ |
553 | 0 | if (!estack->paused) { |
554 | | /* Start the variable-argument parsing */ |
555 | 0 | va_start(ap, fmt); |
556 | 0 | va_started = true; |
557 | | |
558 | | /* Duplicate string information */ |
559 | 0 | if (NULL == (tmp_file = strdup(file))) |
560 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate file string"); |
561 | 0 | if (NULL == (tmp_func = strdup(func))) |
562 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTALLOC, FAIL, "can't duplicate function string"); |
563 | | |
564 | | /* Increment refcount on non-library IDs */ |
565 | 0 | if (cls_id != H5E_ERR_CLS_g) |
566 | 0 | if (H5I_inc_ref(cls_id, false) < 0) |
567 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment class ID"); |
568 | 0 | if (maj_id < H5E_first_maj_id_g || maj_id > H5E_last_maj_id_g) |
569 | 0 | if (H5I_inc_ref(maj_id, false) < 0) |
570 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment major error ID"); |
571 | 0 | if (min_id < H5E_first_min_id_g || min_id > H5E_last_min_id_g) |
572 | 0 | if (H5I_inc_ref(min_id, false) < 0) |
573 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTINC, FAIL, "can't increment minor error ID"); |
574 | | |
575 | | /* Push the error on the stack */ |
576 | 0 | if (H5E__push_stack(estack, true, tmp_file, tmp_func, line, cls_id, maj_id, min_id, fmt, &ap) < 0) |
577 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't push error on stack"); |
578 | 0 | } |
579 | | |
580 | 0 | done: |
581 | 0 | if (va_started) |
582 | 0 | va_end(ap); |
583 | |
|
584 | 0 | FUNC_LEAVE_API(ret_value) |
585 | 0 | } /* end H5Epush2() */ |
586 | | |
587 | | /*------------------------------------------------------------------------- |
588 | | * Function: H5Eclear2 |
589 | | * |
590 | | * Purpose: Clears the error stack for the specified error stack. |
591 | | * |
592 | | * Return: Non-negative on success/Negative on failure |
593 | | * |
594 | | *------------------------------------------------------------------------- |
595 | | */ |
596 | | herr_t |
597 | | H5Eclear2(hid_t err_stack) |
598 | 0 | { |
599 | 0 | H5E_stack_t *estack; /* Error stack to operate on */ |
600 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
601 | | |
602 | | /* Don't clear the error stack! :-) */ |
603 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
604 | | |
605 | | /* Need to check for errors */ |
606 | 0 | if (err_stack == H5E_DEFAULT) |
607 | 0 | estack = NULL; |
608 | 0 | else { |
609 | | /* Only clear the error stack if it's not the default stack */ |
610 | 0 | H5E_clear_stack(); |
611 | |
|
612 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK))) |
613 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
614 | 0 | } /* end else */ |
615 | | |
616 | | /* Clear the error stack */ |
617 | 0 | if (H5E__destroy_stack(estack) < 0) |
618 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't clear error stack"); |
619 | | |
620 | 0 | done: |
621 | 0 | FUNC_LEAVE_API(ret_value) |
622 | 0 | } /* end H5Eclear2() */ |
623 | | |
624 | | /*------------------------------------------------------------------------- |
625 | | * Function: H5Eprint2 |
626 | | * |
627 | | * Purpose: Prints the error stack in some default way. This is just a |
628 | | * convenience function for H5Ewalk() with a function that |
629 | | * prints error messages. Users are encouraged to write their |
630 | | * own more specific error handlers. |
631 | | * |
632 | | * Return: Non-negative on success/Negative on failure |
633 | | * |
634 | | *------------------------------------------------------------------------- |
635 | | */ |
636 | | herr_t |
637 | | H5Eprint2(hid_t err_stack, FILE *stream) |
638 | 0 | { |
639 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
640 | | |
641 | | /* Don't clear the error stack! :-) */ |
642 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
643 | | |
644 | | /* Print error stack */ |
645 | 0 | if ((ret_value = H5E__print2(err_stack, stream)) < 0) |
646 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTLIST, FAIL, "can't display error stack"); |
647 | | |
648 | 0 | done: |
649 | 0 | FUNC_LEAVE_API(ret_value) |
650 | 0 | } /* end H5Eprint2() */ |
651 | | |
652 | | /*------------------------------------------------------------------------- |
653 | | * Function: H5Ewalk2 |
654 | | * |
655 | | * Purpose: Walks the error stack for the current thread and calls some |
656 | | * function for each error along the way. |
657 | | * |
658 | | * Return: Non-negative on success/Negative on failure |
659 | | * |
660 | | *------------------------------------------------------------------------- |
661 | | */ |
662 | | herr_t |
663 | | H5Ewalk2(hid_t err_stack, H5E_direction_t direction, H5E_walk2_t stack_func, void *client_data) |
664 | 0 | { |
665 | 0 | H5E_stack_t *estack; /* Error stack to operate on */ |
666 | 0 | H5E_walk_op_t op; /* Operator for walking error stack */ |
667 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
668 | | |
669 | | /* Don't clear the error stack! :-) */ |
670 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
671 | | |
672 | | /* Need to check for errors */ |
673 | 0 | if (err_stack == H5E_DEFAULT) { |
674 | 0 | if (NULL == (estack = H5E__get_my_stack())) |
675 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
676 | 0 | } /* end if */ |
677 | 0 | else { |
678 | | /* Only clear the error stack if it's not the default stack */ |
679 | 0 | H5E_clear_stack(); |
680 | |
|
681 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(err_stack, H5I_ERROR_STACK))) |
682 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
683 | 0 | } /* end else */ |
684 | | |
685 | | /* Walk the error stack */ |
686 | 0 | op.vers = 2; |
687 | 0 | op.u.func2 = stack_func; |
688 | 0 | if ((ret_value = H5E__walk(estack, direction, &op, client_data)) < 0) |
689 | 0 | HERROR(H5E_ERROR, H5E_CANTLIST, "can't walk error stack"); |
690 | |
|
691 | 0 | done: |
692 | 0 | FUNC_LEAVE_API(ret_value) |
693 | 0 | } /* end H5Ewalk2() */ |
694 | | |
695 | | /*------------------------------------------------------------------------- |
696 | | * Function: H5Eget_auto2 |
697 | | * |
698 | | * Purpose: Returns the current settings for the automatic error stack |
699 | | * traversal function and its data for specific error stack. |
700 | | * Either (or both) arguments may be null in which case the |
701 | | * value is not returned. |
702 | | * |
703 | | * Return: Non-negative value on success/Negative on failure |
704 | | * |
705 | | *------------------------------------------------------------------------- |
706 | | */ |
707 | | herr_t |
708 | | H5Eget_auto2(hid_t estack_id, H5E_auto2_t *func /*out*/, void **client_data /*out*/) |
709 | 0 | { |
710 | 0 | H5E_stack_t *estack; /* Error stack to operate on */ |
711 | 0 | H5E_auto_op_t op; /* Error stack function */ |
712 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
713 | | |
714 | | /* Don't clear the error stack! :-) */ |
715 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
716 | |
|
717 | 0 | if (estack_id == H5E_DEFAULT) { |
718 | 0 | if (NULL == (estack = H5E__get_my_stack())) |
719 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
720 | 0 | } /* end if */ |
721 | 0 | else { |
722 | | /* Only clear the error stack if it's not the default stack */ |
723 | 0 | H5E_clear_stack(); |
724 | |
|
725 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) |
726 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
727 | 0 | } /* end else */ |
728 | | |
729 | | /* Get the automatic error reporting information */ |
730 | 0 | if (H5E__get_auto(estack, &op, client_data) < 0) |
731 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info"); |
732 | | |
733 | 0 | #ifndef H5_NO_DEPRECATED_SYMBOLS |
734 | | /* Fail if the printing function isn't the default(user-set) and set through H5Eset_auto1 */ |
735 | 0 | if (!op.is_default && op.vers == 1) |
736 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "wrong API function, H5Eset_auto1 has been called"); |
737 | 0 | #endif /* H5_NO_DEPRECATED_SYMBOLS */ |
738 | | |
739 | 0 | if (func) |
740 | 0 | *func = op.func2; |
741 | |
|
742 | 0 | done: |
743 | 0 | FUNC_LEAVE_API(ret_value) |
744 | 0 | } /* end H5Eget_auto2() */ |
745 | | |
746 | | /*------------------------------------------------------------------------- |
747 | | * Function: H5Eset_auto2 |
748 | | * |
749 | | * Purpose: Turns on or off automatic printing of errors for certain |
750 | | * error stack. When turned on (non-null FUNC pointer) any |
751 | | * API function which returns an error indication will first |
752 | | * call FUNC passing it CLIENT_DATA as an argument. |
753 | | * |
754 | | * The default values before this function is called are |
755 | | * H5Eprint2() with client data being the standard error stream, |
756 | | * stderr. |
757 | | * |
758 | | * Automatic stack traversal is always in the H5E_WALK_DOWNWARD |
759 | | * direction. |
760 | | * |
761 | | * Return: Non-negative value on success/Negative on failure |
762 | | * |
763 | | *------------------------------------------------------------------------- |
764 | | */ |
765 | | herr_t |
766 | | H5Eset_auto2(hid_t estack_id, H5E_auto2_t func, void *client_data) |
767 | 0 | { |
768 | 0 | H5E_stack_t *estack; /* Error stack to operate on */ |
769 | 0 | H5E_auto_op_t op; /* Error stack operator */ |
770 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
771 | | |
772 | | /* Don't clear the error stack! :-) */ |
773 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
774 | |
|
775 | 0 | if (estack_id == H5E_DEFAULT) { |
776 | 0 | if (NULL == (estack = H5E__get_my_stack())) |
777 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
778 | 0 | } /* end if */ |
779 | 0 | else { |
780 | | /* Only clear the error stack if it's not the default stack */ |
781 | 0 | H5E_clear_stack(); |
782 | |
|
783 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) |
784 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
785 | 0 | } /* end else */ |
786 | | |
787 | 0 | #ifndef H5_NO_DEPRECATED_SYMBOLS |
788 | | /* Get the automatic error reporting information */ |
789 | 0 | if (H5E__get_auto(estack, &op, NULL) < 0) |
790 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info"); |
791 | | |
792 | | /* Set the automatic error reporting information */ |
793 | 0 | if (func != op.func2_default) |
794 | 0 | op.is_default = false; |
795 | 0 | else |
796 | 0 | op.is_default = true; |
797 | |
|
798 | 0 | op.vers = 2; |
799 | 0 | #endif /* H5_NO_DEPRECATED_SYMBOLS */ |
800 | | |
801 | | /* Set the automatic error reporting function */ |
802 | 0 | op.func2 = func; |
803 | |
|
804 | 0 | if (H5E__set_auto(estack, &op, client_data) < 0) |
805 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info"); |
806 | | |
807 | 0 | done: |
808 | 0 | FUNC_LEAVE_API(ret_value) |
809 | 0 | } /* end H5Eset_auto2() */ |
810 | | |
811 | | /*------------------------------------------------------------------------- |
812 | | * Function: H5Eauto_is_v2 |
813 | | * |
814 | | * Purpose: Determines if the error auto reporting function for an |
815 | | * error stack conforms to the H5E_auto_stack_t typedef |
816 | | * or the H5E_auto_t typedef. The IS_STACK parameter is set |
817 | | * to 1 for the first case and 0 for the latter case. |
818 | | * |
819 | | * Return: Non-negative value on success/Negative on failure |
820 | | * |
821 | | *------------------------------------------------------------------------- |
822 | | */ |
823 | | herr_t |
824 | | H5Eauto_is_v2(hid_t estack_id, unsigned *is_stack) |
825 | 0 | { |
826 | 0 | H5E_stack_t *estack; /* Error stack to operate on */ |
827 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
828 | | |
829 | | /* Don't clear the error stack! :-) */ |
830 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
831 | |
|
832 | 0 | if (estack_id == H5E_DEFAULT) { |
833 | 0 | if (NULL == (estack = H5E__get_my_stack())) |
834 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
835 | 0 | } /* end if */ |
836 | 0 | else { |
837 | | /* Only clear the error stack if it's not the default stack */ |
838 | 0 | H5E_clear_stack(); |
839 | |
|
840 | 0 | if (NULL == (estack = (H5E_stack_t *)H5I_object_verify(estack_id, H5I_ERROR_STACK))) |
841 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID"); |
842 | 0 | } /* end else */ |
843 | | |
844 | | /* Check if the error stack reporting function is the "newer" stack type */ |
845 | 0 | if (is_stack) |
846 | 0 | #ifndef H5_NO_DEPRECATED_SYMBOLS |
847 | 0 | *is_stack = estack->auto_op.vers > 1; |
848 | | #else |
849 | | *is_stack = 1; |
850 | | #endif |
851 | |
|
852 | 0 | done: |
853 | 0 | FUNC_LEAVE_API(ret_value) |
854 | 0 | } /* end H5Eauto_is_v2() */ |
855 | | |
856 | | /*------------------------------------------------------------------------- |
857 | | * Function: H5Eappend_stack |
858 | | * |
859 | | * Purpose: Appends one error stack to another, optionally closing the |
860 | | * source stack. |
861 | | * |
862 | | * Return: Non-negative value on success/Negative on failure |
863 | | * |
864 | | *------------------------------------------------------------------------- |
865 | | */ |
866 | | herr_t |
867 | | H5Eappend_stack(hid_t dst_stack_id, hid_t src_stack_id, bool close_source_stack) |
868 | 0 | { |
869 | 0 | H5E_stack_t *dst_stack, *src_stack; /* Error stacks */ |
870 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
871 | |
|
872 | 0 | FUNC_ENTER_API(FAIL) |
873 | | |
874 | | /* Check args */ |
875 | 0 | if (NULL == (dst_stack = (H5E_stack_t *)H5I_object_verify(dst_stack_id, H5I_ERROR_STACK))) |
876 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dst_stack_id not a error stack ID"); |
877 | 0 | if (NULL == (src_stack = (H5E_stack_t *)H5I_object_verify(src_stack_id, H5I_ERROR_STACK))) |
878 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "src_stack_id not a error stack ID"); |
879 | | |
880 | | /* Append the source stack to the destination stack */ |
881 | 0 | if (H5E__append_stack(dst_stack, src_stack) < 0) |
882 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTAPPEND, FAIL, "can't append stack"); |
883 | | |
884 | | /* Close source error stack, if requested */ |
885 | 0 | if (close_source_stack) |
886 | | /* Decrement the counter on the error stack. It will be freed if the |
887 | | * count reaches zero. |
888 | | */ |
889 | 0 | if (H5I_dec_app_ref(src_stack_id) < 0) |
890 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTDEC, FAIL, "unable to decrement ref count on source error stack"); |
891 | | |
892 | 0 | done: |
893 | 0 | FUNC_LEAVE_API(ret_value) |
894 | 0 | } /* end H5Eappend_stack() */ |
895 | | |
896 | | /*------------------------------------------------------------------------- |
897 | | * Function: H5Eis_paused |
898 | | * |
899 | | * Purpose: Check if pushing errors on an error stack is paused |
900 | | * |
901 | | * Return: Non-negative value on success/Negative on failure |
902 | | * |
903 | | *------------------------------------------------------------------------- |
904 | | */ |
905 | | herr_t |
906 | | H5Eis_paused(hid_t stack_id, bool *is_paused) |
907 | 0 | { |
908 | 0 | H5E_stack_t *stack; /* Error stack */ |
909 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
910 | | |
911 | | /* Don't clear the error stack! :-) */ |
912 | 0 | FUNC_ENTER_API_NOCLEAR(FAIL) |
913 | | |
914 | | /* Get the correct error stack */ |
915 | 0 | if (stack_id == H5E_DEFAULT) { |
916 | 0 | if (NULL == (stack = H5E__get_my_stack())) |
917 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
918 | 0 | } /* end if */ |
919 | 0 | else { |
920 | | /* Only clear the error stack if it's not the default stack */ |
921 | 0 | H5E_clear_stack(); |
922 | | |
923 | | /* Get the error stack to operate on */ |
924 | 0 | if (NULL == (stack = (H5E_stack_t *)H5I_object_verify(stack_id, H5I_ERROR_STACK))) |
925 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack ID"); |
926 | 0 | } /* end else */ |
927 | | |
928 | | /* Check arguments */ |
929 | 0 | if (NULL == is_paused) |
930 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "is_paused parameter is NULL"); |
931 | | |
932 | | /* Check if the stack is paused */ |
933 | 0 | *is_paused = (stack->paused > 0); |
934 | |
|
935 | 0 | done: |
936 | 0 | FUNC_LEAVE_API(ret_value) |
937 | 0 | } /* end H5Eis_paused() */ |
938 | | |
939 | | /*------------------------------------------------------------------------- |
940 | | * Function: H5Epause_stack |
941 | | * |
942 | | * Purpose: Pause pushing errors on an error stack |
943 | | * |
944 | | * Return: Non-negative value on success/Negative on failure |
945 | | * |
946 | | *------------------------------------------------------------------------- |
947 | | */ |
948 | | herr_t |
949 | | H5Epause_stack(hid_t stack_id) |
950 | 0 | { |
951 | 0 | H5E_stack_t *stack; /* Error stack */ |
952 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
953 | |
|
954 | 0 | FUNC_ENTER_API(FAIL) |
955 | | |
956 | | /* Get the correct error stack */ |
957 | 0 | if (stack_id == H5E_DEFAULT) { |
958 | 0 | if (NULL == (stack = H5E__get_my_stack())) |
959 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
960 | 0 | } /* end if */ |
961 | 0 | else |
962 | | /* Get the error stack to operate on */ |
963 | 0 | if (NULL == (stack = (H5E_stack_t *)H5I_object_verify(stack_id, H5I_ERROR_STACK))) |
964 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack ID"); |
965 | | |
966 | | /* Increment pause counter */ |
967 | 0 | stack->paused++; |
968 | |
|
969 | 0 | done: |
970 | 0 | FUNC_LEAVE_API(ret_value) |
971 | 0 | } /* end H5Epause_stack() */ |
972 | | |
973 | | /*------------------------------------------------------------------------- |
974 | | * Function: H5Eresume_stack |
975 | | * |
976 | | * Purpose: Resume pushing errors on an error stack |
977 | | * |
978 | | * Return: Non-negative value on success/Negative on failure |
979 | | * |
980 | | *------------------------------------------------------------------------- |
981 | | */ |
982 | | herr_t |
983 | | H5Eresume_stack(hid_t stack_id) |
984 | 0 | { |
985 | 0 | H5E_stack_t *stack; /* Error stack */ |
986 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
987 | |
|
988 | 0 | FUNC_ENTER_API(FAIL) |
989 | | |
990 | | /* Get the correct error stack */ |
991 | 0 | if (stack_id == H5E_DEFAULT) { |
992 | 0 | if (NULL == (stack = H5E__get_my_stack())) |
993 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack"); |
994 | 0 | } /* end if */ |
995 | 0 | else |
996 | | /* Get the error stack to operate on */ |
997 | 0 | if (NULL == (stack = (H5E_stack_t *)H5I_object_verify(stack_id, H5I_ERROR_STACK))) |
998 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an error stack ID"); |
999 | | |
1000 | | /* Check for pause/resume imbalance */ |
1001 | 0 | if (0 == stack->paused) |
1002 | 0 | HGOTO_ERROR(H5E_ERROR, H5E_BADRANGE, FAIL, "resuming more than paused"); |
1003 | | |
1004 | | /* Decrement pause counter */ |
1005 | 0 | stack->paused--; |
1006 | |
|
1007 | 0 | done: |
1008 | | FUNC_LEAVE_API(ret_value) |
1009 | 0 | } /* end H5Eresume_stack() */ |