1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #ifndef _h_klib_rc_
28 #define _h_klib_rc_
29 
30 #ifndef _h_klib_extern_
31 #include <klib/extern.h>
32 #endif
33 
34 #ifndef _h_klib_defs_
35 #include <klib/defs.h>
36 #endif
37 
38 #if _DEBUGGING
39 
40 #ifndef _h_compiler_
41 #include <compiler.h>
42 #endif
43 
44 #include <assert.h>
45 #endif
46 
47 
48 /*--------------------------------------------------------------------------
49  * RC
50  *  upon success, all functions will return code 0
51  *  other codes indicate failure or additional status information
52  */
53 
54 #if _DEBUGGING && ! defined RECORD_RC_FILE_LINE
55 #define RECORD_RC_FILE_LINE 1
56 #elif ! defined RECORD_RC_FILE_LINE
57 #define RECORD_RC_FILE_LINE 0
58 #endif
59 
60 /* actual code declarations are in <kfc/rc.h> */
61 #include <kfc/rc.h>
62 
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66 
67 #if RC_EMIT
68 
69 KLIB_EXTERN const char * CC GetRCFilename ( void );
70 KLIB_EXTERN const char * CC GetRCFunction ( void );
71 KLIB_EXTERN uint32_t CC GetRCLineno ( void );
72 KLIB_EXTERN rc_t CC SetRCFileFuncLine ( rc_t rc, const char *filename, const char *funcname, uint32_t lineno );
73 KLIB_EXTERN bool CC GetUnreadRCInfo ( rc_t *rc, const char **filename, const char **funcname, uint32_t *lineno );
74 
75 #if RECORD_RC_FILE_LINE
76 
77     #if defined(__SUNPRO_CC)  &&  __SUNPRO_CC <= 0x590  &&  defined(__cplusplus)
78 
79         #define SET_RC_FILE_FUNC_LINE( rc ) \
80             SetRCFileFuncLine ( ( rc ), __FILE__, "(unknown)", __LINE__ )
81 
82     #else
83 
84         #define SET_RC_FILE_FUNC_LINE( rc ) \
85             SetRCFileFuncLine ( ( rc ), __FILE__, __func__, __LINE__ )
86 
87     #endif
88 
89 #else
90 
91     #define SET_RC_FILE_FUNC_LINE( rc ) \
92         ( rc_t ) ( rc )
93 
94 #endif
95 
96 #ifdef assert
97 #define ASSERT_MOD_TARG_CTX()                                    \
98     assert ( ( int ) rcKFG == ( int ) rcSRA + 1 ),               \
99     assert ( ( int ) rcProduction == ( int ) rcExpression + 1 ), \
100     assert ( ( int ) rcFlushing == ( int ) rcInflating + 1 ),    \
101     assert ( ( int ) rcLastModule_v1_1  <= ( 1 << 5 ) ),         \
102     assert ( ( int ) rcLastTarget_v1_1  <= ( 1 << 6 ) ),         \
103     assert ( ( int ) rcLastContext_v1_1  <= ( 1 << 7 ) )
104 
105 #define ASSERT_OBJ_STATE() \
106     assert ( ( int ) rcLink == ( int ) rcUri + 1 ),              \
107     assert ( ( int ) rcItem == ( int ) rcLibrary + 1 ),          \
108     assert ( ( int ) rcOpen == ( int ) rcOutofrange + 1 ),       \
109     assert ( ( int ) rcLastObject_v1_1  <= ( 1 << 8 ) ),         \
110     assert ( ( int ) rcLastState_v1_1  <= ( 1 << 6 ) )
111 #else
112 #define ASSERT_MOD_TARG_CTX() ( void ) 0
113 
114 #define ASSERT_OBJ_STATE() ( void ) 0
115 #endif
116 
117 /* CTX
118  *  form a context from parts
119  */
120 #define CTX( mod, targ, ctx )                                \
121     ( rc_t ) ( ASSERT_MOD_TARG_CTX (),                       \
122                RAW_CTX ( mod, targ, ctx ) )
123 
124 /* RC
125  *  form a complete return code from parts
126  */
127 #define SILENT_RC( mod, targ, ctx, obj, state )              \
128     ( rc_t ) ( ASSERT_OBJ_STATE (),                          \
129         CTX ( mod, targ, ctx )    | /* 18 bits */            \
130         ( ( rc_t ) ( obj ) << 6 ) | /*  8 bits */            \
131         ( ( rc_t ) ( state ) ) )    /*  6 bits */
132 
133 #define RC( mod, targ, ctx, obj, state )                     \
134     ( rc_t ) ( ASSERT_OBJ_STATE (),                          \
135     SET_RC_FILE_FUNC_LINE (                                  \
136         CTX ( mod, targ, ctx )    | /* 18 bits */            \
137         ( ( rc_t ) ( obj ) << 6 ) | /*  8 bits */            \
138         ( ( rc_t ) ( state ) ) ) )  /*  6 bits */
139 
140 /* RC_FROM_CTX
141  *  form an rc but take input from existing CTX()
142  */
143 #define RC_FROM_CTX( ctx, obj, state )                       \
144     ( rc_t ) ( ASSERT_OBJ_STATE (),                          \
145     SET_RC_FILE_FUNC_LINE (                                  \
146         ( ctx )                   | /* 18 bits */            \
147         ( ( rc_t ) ( obj ) << 6 ) | /*  8 bits */            \
148         ( ( rc_t ) ( state ) ) ) )  /*  6 bits */
149 
150 /* RC_EXITCODE
151  *  form an rc from the desired process exit code
152  */
153 #define RC_EXITCODE( exitcode )                             \
154     ( ( rc_t )( CTX ( rcExitCode, rcProcess, rcClosing ) |  \
155     ( ( rc_t )( ( ( unsigned ) (exitcode) ) & 0x7F ) ) ) )
156 
157 #define IF_EXITCODE( rc, default_exit_code )                \
158     ( (int) ( (int) GetRCModule(rc) == (int) rcExitCode ) ? \
159       ( ((unsigned)rc) & 0x7F ) : ( default_exit_code ) )
160 
161 /* ResetRCContext
162  *  rewrite rc to reflect different context
163  *  typically used to pass out return codes
164  */
165 #define ResetRCContext( rc, mod, targ, ctx ) \
166     ( ( ( rc ) & 0x3FFF ) | CTX ( mod, targ, ctx ) )
167 
168 /* ResetRCState
169  *  rewrite rc to reflect different state
170  *  typically used to pass out return codes
171  */
172 #define ResetRCState( rc, obj, state ) \
173     ( ( ( rc ) & 0xFFFFFFC0 ) | ( rc_t ) ( state ) )
174 
175 #endif /* __cplusplus */
176 
177 /* GetRCModule
178  *  extract the module portion
179  */
180 #define GetRCModule( rc ) \
181     ( enum RCModule ) ( ( ( rc ) >> 27 ) & 0x1F )
182 
183 /* GetRCTarget
184  *  extract the target portion
185  */
186 #define GetRCTarget( rc ) \
187     ( enum RCTarget ) ( ( ( rc ) >> 21 ) & 0x3F )
188 
189 /* GetRCContext
190  *  extract the context portion
191  */
192 #define GetRCContext( rc ) \
193     ( enum RCContext ) ( ( ( rc ) >> 14 ) & 0x7F )
194 
195 /* GetRCObject
196  *  extract the target object portion
197  */
198 #define GetRCObject( rc ) \
199     ( enum RCObject ) ( ( ( rc ) >> 6 ) & 0xFF )
200 
201 /* GetRCState
202  *  extract the state portion
203  */
204 #define GetRCState( rc ) \
205     ( enum RCState ) ( ( rc ) & 0x3F )
206 
207 
208 #ifdef __cplusplus
209 }
210 #endif
211 
212 #endif /*  _h_klib_rc_ */
213