diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2004-09-09 02:37:02 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2004-09-09 02:37:02 (GMT) |
commit | eb3e9ccd8ac3e1a69d0f9bc2c9e9f1c2b5108f21 (patch) | |
tree | 5a15644f3f46cb73b22605f3d03b36918bbbd065 /src | |
parent | 4389b976a5af4d4ca755f4ddab2e2e9ed861ea1e (diff) | |
download | hdf5-eb3e9ccd8ac3e1a69d0f9bc2c9e9f1c2b5108f21.zip hdf5-eb3e9ccd8ac3e1a69d0f9bc2c9e9f1c2b5108f21.tar.gz hdf5-eb3e9ccd8ac3e1a69d0f9bc2c9e9f1c2b5108f21.tar.bz2 |
[svn-r9234] Purpose:
Code cleanup
Description:
Tweak recent "forward compatibility" changes to the H5E* API (which allowed
for the old H5E API functions to remain unchanged) by allowing for the error
stack callback function (H5E_auto_t) to also remain unchanged from the 1.6
branch. This required changing the H5E{get|set}_auto routines to have the
old style H5E_auto_t type (which didn't have a stack ID parameter) and the new
H5E{get|set}_auto_stack routines to have a newer "H5E_auto_stack_t" type (which
has a stack ID parameter). This should make the H5E API changes as forwardly
compatible as possible.
One side-affect of this change was that it was impossible to determine if
the current auto error callback was the old style (H5E_auto_t) or the new style
(H5E_auto_stack_t) of callback, so a new API function (H5Eauto_is_stack) was
adde to query this.
Platforms tested:
FreeBSD 4.10 (sleipnir)
IRIX64 6.5 (modi4)
h5committest
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 2 | ||||
-rw-r--r-- | src/H5E.c | 94 | ||||
-rw-r--r-- | src/H5Eprivate.h | 6 | ||||
-rw-r--r-- | src/H5Epublic.h | 37 | ||||
-rw-r--r-- | src/H5MPprivate.h | 1 | ||||
-rw-r--r-- | src/H5Tnative.c | 137 |
6 files changed, 178 insertions, 99 deletions
@@ -181,7 +181,7 @@ H5_term_library(void) int pending, ntries=0, n; unsigned at=0; char loop[1024]; - H5E_auto_t func; + H5E_auto_stack_t func; #ifdef H5_HAVE_THREADSAFE /* explicit locking of the API */ @@ -113,8 +113,8 @@ static herr_t H5E_print_stack(const H5E_t *estack, FILE *stream); static herr_t H5E_walk_stack(const H5E_t *estack, H5E_direction_t direction, H5E_walk_t func, void *client_data); static herr_t H5E_walk_cb(unsigned n, const H5E_error_t *err_desc, void *client_data); -static herr_t H5E_get_auto_stack(const H5E_t *estack, H5E_auto_t *func, void **client_data); -static herr_t H5E_set_auto_stack(H5E_t *estack, H5E_auto_t func, void *client_data); +static herr_t H5E_get_auto_stack(const H5E_t *estack, hbool_t new_api, void **func, void **client_data); +static herr_t H5E_set_auto_stack(H5E_t *estack, hbool_t new_api, void *func, void *client_data); /*------------------------------------------------------------------------- @@ -183,9 +183,11 @@ H5E_init_interface(void) #ifndef H5_HAVE_THREADSAFE H5E_stack_g[0].nused = 0; #ifdef H5_WANT_H5_V1_6_COMPAT - H5E_stack_g[0].func = (H5E_auto_t)H5Eprint; + H5E_stack_g[0].new_api = FALSE; + H5E_stack_g[0].u.func = (H5E_auto_t)H5Eprint; #else /*H5_WANT_H5_V1_6_COMPAT*/ - H5E_stack_g[0].func = (H5E_auto_t)H5Eprint_stack; + H5E_stack_g[0].new_api = TRUE; + H5E_stack_g[0].u.func_stack = (H5E_auto_stack_t)H5Eprint_stack; #endif /*H5_WANT_H5_V1_6_COMPAT*/ H5E_stack_g[0].auto_data = NULL; #endif /* H5_HAVE_THREADSAFE */ @@ -310,7 +312,8 @@ H5E_get_stack(void) /* no associated value with current thread - create one */ estack = (H5E_t *)H5MM_malloc(sizeof(H5E_t)); estack->nused = 0; - estack->func = (H5E_auto_t)H5Eprint_stack; + estack->new_api = TRUE; + estack->u.func_stack = (H5E_auto_stack_t)H5Eprint_stack; estack->auto_data = NULL; pthread_setspecific(H5TS_errstk_key_g, (void *)estack); } @@ -2240,12 +2243,12 @@ H5Eget_auto(H5E_auto_t *func, void **client_data) FUNC_ENTER_API(H5Eget_auto, FAIL) H5TRACE2("e","*xx",func,client_data); - /* Retieve default error stack */ + /* Retrieve default error stack */ if((estack = H5E_get_my_stack())==NULL) /*lint !e506 !e774 Make lint 'constant value Boolean' in non-threaded case */ HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") /* Get the automatic error reporting information */ - if(H5E_get_auto_stack(estack, func, client_data)<0) + if(H5E_get_auto_stack(estack, FALSE, (void **)func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") done: @@ -2275,7 +2278,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Eget_auto_stack(hid_t estack_id, H5E_auto_t *func, void **client_data) +H5Eget_auto_stack(hid_t estack_id, H5E_auto_stack_t *func, void **client_data) { H5E_t *estack; /* Error stack to operate on */ herr_t ret_value=SUCCEED; /* Return value */ @@ -2292,7 +2295,7 @@ H5Eget_auto_stack(hid_t estack_id, H5E_auto_t *func, void **client_data) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") /* Get the automatic error reporting information */ - if(H5E_get_auto_stack(estack, func, client_data)<0) + if(H5E_get_auto_stack(estack, TRUE, (void **)func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get automatic error info") done: @@ -2318,7 +2321,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E_get_auto_stack(const H5E_t *estack, H5E_auto_t *func, void **client_data) +H5E_get_auto_stack(const H5E_t *estack, hbool_t new_api, void * *func, void **client_data) { herr_t ret_value=SUCCEED; /* Return value */ @@ -2327,7 +2330,8 @@ H5E_get_auto_stack(const H5E_t *estack, H5E_auto_t *func, void **client_data) assert (estack); /* Retrieve the requested information */ - if(func) *func = estack->func; + if(func) + *func = new_api ? (void *)estack->u.func_stack : (void *)estack->u.func; if(client_data) *client_data = estack->auto_data; done: @@ -2375,7 +2379,7 @@ H5Eset_auto(H5E_auto_t func, void *client_data) HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") /* Set the automatic error reporting information */ - if(H5E_set_auto_stack(estack, func, client_data)<0) + if(H5E_set_auto_stack(estack, FALSE, (void *)func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info") done: @@ -2410,7 +2414,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Eset_auto_stack(hid_t estack_id, H5E_auto_t func, void *client_data) +H5Eset_auto_stack(hid_t estack_id, H5E_auto_stack_t func, void *client_data) { H5E_t *estack; /* Error stack to operate on */ herr_t ret_value=SUCCEED; /* Return value */ @@ -2427,7 +2431,7 @@ H5Eset_auto_stack(hid_t estack_id, H5E_auto_t func, void *client_data) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") /* Set the automatic error reporting information */ - if(H5E_set_auto_stack(estack, func, client_data)<0) + if(H5E_set_auto_stack(estack, TRUE, (void *)func, client_data)<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTSET, FAIL, "can't set automatic error info") done: @@ -2463,7 +2467,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5E_set_auto_stack(H5E_t *estack, H5E_auto_t func, void *client_data) +H5E_set_auto_stack(H5E_t *estack, hbool_t new_api, void *func, void *client_data) { herr_t ret_value=SUCCEED; /* Return value */ @@ -2472,7 +2476,11 @@ H5E_set_auto_stack(H5E_t *estack, H5E_auto_t func, void *client_data) assert(estack); /* Set the automatic error reporting info */ - estack->func = func; + estack->new_api = new_api; + if(new_api) + estack->u.func_stack = (H5E_auto_stack_t)func; + else + estack->u.func = (H5E_auto_t)func; estack->auto_data = client_data; done: @@ -2508,10 +2516,60 @@ H5E_dump_api_stack(int is_api) H5E_t *estack = H5E_get_my_stack(); assert(estack); - if (estack->func) - (void)((estack->func)(H5E_DEFAULT, estack->auto_data)); + if(estack->new_api) { + if (estack->u.func_stack) + (void)((estack->u.func_stack)(H5E_DEFAULT, estack->auto_data)); + } /* end if */ + else { + if (estack->u.func) + (void)((estack->u.func)(estack->auto_data)); + } /* end else */ } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) } + + +/*------------------------------------------------------------------------- + * Function: H5Eauto_is_stack + * + * Purpose: Determines if the error auto reporting function for an + * error stack conforms to the H5E_auto_stack_t typedef + * or the H5E_auto_t typedef. The IS_STACK parameter is set + * to 1 for the first case and 0 for the latter case. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Wednesday, September 8, 2004 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Eauto_is_stack(hid_t estack_id, unsigned *is_stack) +{ + H5E_t *estack; /* Error stack to operate on */ + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Eauto_is_stack, FAIL) + H5TRACE2("e","ix",estack_id,is_stack); + + if(estack_id == H5E_DEFAULT) { + if((estack = H5E_get_my_stack())==NULL) /*lint !e506 !e774 Make lint 'constant value Boolean' in non-threaded case */ + HGOTO_ERROR(H5E_ERROR, H5E_CANTGET, FAIL, "can't get current error stack") + } /* end if */ + else + if((estack = H5I_object_verify(estack_id, H5I_ERROR_STACK))==NULL) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a error stack ID") + + /* Check if the error stack reporting function is the "newer" stack type */ + if(is_stack) + *is_stack=estack->new_api; + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Eauto_is_stack() */ + diff --git a/src/H5Eprivate.h b/src/H5Eprivate.h index 4dbb670..9c5744f 100644 --- a/src/H5Eprivate.h +++ b/src/H5Eprivate.h @@ -44,7 +44,11 @@ typedef struct H5E_msg_t { typedef struct H5E_t { size_t nused; /* Num slots currently used in stack */ H5E_error_t slot[H5E_NSLOTS]; /* Array of error records */ - H5E_auto_t func; /* Function for 'automatic' error reporting */ + hbool_t new_api; /* Indicate that the function pointer is for the new (stack) API or the old */ + union { + H5E_auto_t func; /* Function for 'automatic' error reporting */ + H5E_auto_stack_t func_stack; /* Function for 'automatic' error reporting */ + } u; void *auto_data; /* Callback data for 'automatic error reporting */ } H5E_t; diff --git a/src/H5Epublic.h b/src/H5Epublic.h index 247767c..d5581dd 100644 --- a/src/H5Epublic.h +++ b/src/H5Epublic.h @@ -85,13 +85,28 @@ H5_DLLVAR hid_t H5E_ERR_CLS_g; * purpose. */ #define H5E_BEGIN_TRY { \ - H5E_auto_t H5E_saved_efunc; \ + unsigned H5E_saved_is_stack; \ + union { \ + H5E_auto_stack_t stack_efunc; \ + H5E_auto_t efunc; \ + } H5E_saved; \ void *H5E_saved_edata; \ - (void)H5Eget_auto_stack(H5E_DEFAULT, &H5E_saved_efunc, &H5E_saved_edata); \ - (void)H5Eset_auto_stack(H5E_DEFAULT, NULL, NULL); + \ + (void)H5Eauto_is_stack(H5E_DEFAULT, &H5E_saved_is_stack); \ + if(H5E_saved_is_stack) { \ + (void)H5Eget_auto_stack(H5E_DEFAULT, &H5E_saved.stack_efunc, &H5E_saved_edata); \ + (void)H5Eset_auto_stack(H5E_DEFAULT, NULL, NULL); \ + } else { \ + (void)H5Eget_auto(&H5E_saved.efunc, &H5E_saved_edata); \ + (void)H5Eset_auto(NULL, NULL); \ + } #define H5E_END_TRY \ - (void)H5Eset_auto_stack(H5E_DEFAULT, H5E_saved_efunc, H5E_saved_edata); \ + if(H5E_saved_is_stack) { \ + (void)H5Eset_auto_stack(H5E_DEFAULT, H5E_saved.stack_efunc, H5E_saved_edata); \ + } else { \ + (void)H5Eset_auto(H5E_saved.efunc, H5E_saved_edata); \ + } \ } /* @@ -131,7 +146,8 @@ extern "C" { /* Error stack traversal callback function pointers */ typedef herr_t (*H5E_walk_t)(unsigned n, const H5E_error_t *err_desc, void *client_data); -typedef herr_t (*H5E_auto_t)(hid_t estack, void *client_data); +typedef herr_t (*H5E_auto_t)(void *client_data); +typedef herr_t (*H5E_auto_stack_t)(hid_t estack, void *client_data); /* Public API functions */ H5_DLL hid_t H5Eregister_class(const char *cls_name, const char *lib_name, const char *version); @@ -142,9 +158,10 @@ H5_DLL hid_t H5Eget_current_stack(void); H5_DLL herr_t H5Eclose_stack(hid_t stack_id); H5_DLL ssize_t H5Eget_class_name(hid_t class_id, char *name, size_t size); H5_DLL ssize_t H5Eget_msg(hid_t msg_id, H5E_type_t *type, char *msg, size_t size); -H5_DLL int H5Eget_num(hid_t error_stack_id); -H5_DLL herr_t H5Eset_current_stack(hid_t err_stack_id); -H5_DLL herr_t H5Epop(hid_t err_stack, size_t count); +H5_DLL int H5Eget_num(hid_t error_stack_id); +H5_DLL herr_t H5Eset_current_stack(hid_t err_stack_id); +H5_DLL herr_t H5Epop(hid_t err_stack, size_t count); +H5_DLL herr_t H5Eauto_is_stack(hid_t err_stack, unsigned *is_stack); /* These old APIs are kept for backward compatibility. They don't have * the error stack in the parameters. */ @@ -166,8 +183,8 @@ H5_DLL herr_t H5Epush_stack(hid_t err_stack, const char *file, const char *func H5_DLL herr_t H5Eprint_stack(hid_t err_stack, FILE *stream); H5_DLL herr_t H5Ewalk_stack(hid_t err_stack, H5E_direction_t direction, H5E_walk_t func, void *client_data); -H5_DLL herr_t H5Eget_auto_stack(hid_t estack_id, H5E_auto_t *func, void **client_data); -H5_DLL herr_t H5Eset_auto_stack(hid_t estack_id, H5E_auto_t func, void *client_data); +H5_DLL herr_t H5Eget_auto_stack(hid_t estack_id, H5E_auto_stack_t *func, void **client_data); +H5_DLL herr_t H5Eset_auto_stack(hid_t estack_id, H5E_auto_stack_t func, void *client_data); H5_DLL herr_t H5Eclear_stack(hid_t err_stack); #ifdef __cplusplus } diff --git a/src/H5MPprivate.h b/src/H5MPprivate.h index 401d407..24e7c45 100644 --- a/src/H5MPprivate.h +++ b/src/H5MPprivate.h @@ -121,6 +121,7 @@ #define color_H5Eunregister_class "red" #define color_H5Ewalk "red" #define color_H5Ewalk_stack "red" +#define color_H5Eauto_is_stack "red" #define color_H5Fis_hdf5 "red" #define color_H5Fcreate "red" diff --git a/src/H5Tnative.c b/src/H5Tnative.c index aeba729..9ae0be7 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -535,71 +535,70 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, FUNC_ENTER_NOAPI(H5T_get_native_integer, NULL); - if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) - { - if(prec<=H5Tget_precision(H5T_NATIVE_SCHAR)) { - match=H5T_NATIVE_INT_MATCH_CHAR; - native_size = sizeof(char); - } else if(prec<=H5Tget_precision(H5T_NATIVE_SHORT)) { - match=H5T_NATIVE_INT_MATCH_SHORT; - native_size = sizeof(short); - } else if(prec<=H5Tget_precision(H5T_NATIVE_INT)) { - match=H5T_NATIVE_INT_MATCH_INT; - native_size = sizeof(int); - } else if(prec<=H5Tget_precision(H5T_NATIVE_LONG)) { - match=H5T_NATIVE_INT_MATCH_LONG; - native_size = sizeof(long); - } else if(prec<=H5Tget_precision(H5T_NATIVE_LLONG)) { - match=H5T_NATIVE_INT_MATCH_LLONG; - native_size = sizeof(long_long); - } else { /* If no native type matches the querried datatype, simply choose the type of biggest size. */ - match=H5T_NATIVE_INT_MATCH_LLONG; - native_size = sizeof(long_long); - } - } else if(direction == H5T_DIR_DESCEND) { - if(prec>=H5Tget_precision(H5T_NATIVE_LLONG)) { - match=H5T_NATIVE_INT_MATCH_LLONG; - native_size = sizeof(long_long); - } else if(prec>=H5Tget_precision(H5T_NATIVE_LONG)) { - if(prec==H5Tget_precision(H5T_NATIVE_LONG)) { - match=H5T_NATIVE_INT_MATCH_LONG; - native_size = sizeof(long); - } else { - match=H5T_NATIVE_INT_MATCH_LLONG; - native_size = sizeof(long_long); - } - } - else if(prec>=H5Tget_precision(H5T_NATIVE_INT)) { - if(prec==H5Tget_precision(H5T_NATIVE_INT)) { - match=H5T_NATIVE_INT_MATCH_INT; - native_size = sizeof(int); - } else { - match=H5T_NATIVE_INT_MATCH_LONG; - native_size = sizeof(long); - } - } - else if(prec>=H5Tget_precision(H5T_NATIVE_SHORT)) { - if(prec==H5Tget_precision(H5T_NATIVE_SHORT)) { - match=H5T_NATIVE_INT_MATCH_SHORT; - native_size = sizeof(short); - } else { - match=H5T_NATIVE_INT_MATCH_INT; - native_size = sizeof(int); - } - } - else if(prec>=H5Tget_precision(H5T_NATIVE_SCHAR)) { - if(prec==H5Tget_precision(H5T_NATIVE_SCHAR)) { - match=H5T_NATIVE_INT_MATCH_CHAR; - native_size = sizeof(char); - } else { - match=H5T_NATIVE_INT_MATCH_SHORT; - native_size = sizeof(short); - } - } - else { /* If no native type matches the querried datatype, simple choose the type of smallest size. */ - match=H5T_NATIVE_INT_MATCH_CHAR; - native_size = sizeof(char); - } + if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { + if(prec<=H5Tget_precision(H5T_NATIVE_SCHAR)) { + match=H5T_NATIVE_INT_MATCH_CHAR; + native_size = sizeof(char); + } else if(prec<=H5Tget_precision(H5T_NATIVE_SHORT)) { + match=H5T_NATIVE_INT_MATCH_SHORT; + native_size = sizeof(short); + } else if(prec<=H5Tget_precision(H5T_NATIVE_INT)) { + match=H5T_NATIVE_INT_MATCH_INT; + native_size = sizeof(int); + } else if(prec<=H5Tget_precision(H5T_NATIVE_LONG)) { + match=H5T_NATIVE_INT_MATCH_LONG; + native_size = sizeof(long); + } else if(prec<=H5Tget_precision(H5T_NATIVE_LLONG)) { + match=H5T_NATIVE_INT_MATCH_LLONG; + native_size = sizeof(long_long); + } else { /* If no native type matches the querried datatype, simply choose the type of biggest size. */ + match=H5T_NATIVE_INT_MATCH_LLONG; + native_size = sizeof(long_long); + } + } else if(direction == H5T_DIR_DESCEND) { + if(prec>=H5Tget_precision(H5T_NATIVE_LLONG)) { + match=H5T_NATIVE_INT_MATCH_LLONG; + native_size = sizeof(long_long); + } else if(prec>=H5Tget_precision(H5T_NATIVE_LONG)) { + if(prec==H5Tget_precision(H5T_NATIVE_LONG)) { + match=H5T_NATIVE_INT_MATCH_LONG; + native_size = sizeof(long); + } else { + match=H5T_NATIVE_INT_MATCH_LLONG; + native_size = sizeof(long_long); + } + } + else if(prec>=H5Tget_precision(H5T_NATIVE_INT)) { + if(prec==H5Tget_precision(H5T_NATIVE_INT)) { + match=H5T_NATIVE_INT_MATCH_INT; + native_size = sizeof(int); + } else { + match=H5T_NATIVE_INT_MATCH_LONG; + native_size = sizeof(long); + } + } + else if(prec>=H5Tget_precision(H5T_NATIVE_SHORT)) { + if(prec==H5Tget_precision(H5T_NATIVE_SHORT)) { + match=H5T_NATIVE_INT_MATCH_SHORT; + native_size = sizeof(short); + } else { + match=H5T_NATIVE_INT_MATCH_INT; + native_size = sizeof(int); + } + } + else if(prec>=H5Tget_precision(H5T_NATIVE_SCHAR)) { + if(prec==H5Tget_precision(H5T_NATIVE_SCHAR)) { + match=H5T_NATIVE_INT_MATCH_CHAR; + native_size = sizeof(char); + } else { + match=H5T_NATIVE_INT_MATCH_SHORT; + native_size = sizeof(short); + } + } + else { /* If no native type matches the queried datatype, simply choose the type of smallest size. */ + match=H5T_NATIVE_INT_MATCH_CHAR; + native_size = sizeof(char); + } } /* Set the appropriate native datatype information */ @@ -656,17 +655,17 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, /* Create new native type */ assert(tid>=0); if(NULL==(dt=H5I_object(tid))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy type"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy type") /* compute size and offset of compound type member. */ if(H5T_cmp_offset(comp_size, offset, native_size, 1, align, struct_align)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset"); + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } |