GME  13
svn_error.h
Go to the documentation of this file.
00001 
00027 #ifndef SVN_ERROR_H
00028 #define SVN_ERROR_H
00029 
00030 #include <apr.h>        /* for apr_size_t */
00031 #include <apr_errno.h>  /* APR's error system */
00032 #include <apr_pools.h>  /* for apr_pool_t */
00033 
00034 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00035 #define APR_WANT_STDIO
00036 #endif
00037 #include <apr_want.h>   /* for FILE* */
00038 
00039 #include "svn_types.h"
00040 
00041 #ifdef __cplusplus
00042 extern "C" {
00043 #endif /* __cplusplus */
00044 
00045 
00046 /* For the Subversion developers, this #define turns on extended "stack
00047    traces" of any errors that get thrown. See the SVN_ERR() macro.  */
00048 #ifdef SVN_DEBUG
00049 #define SVN_ERR__TRACING
00050 #endif
00051 
00052 
00054 #define SVN_NO_ERROR   0
00055 
00056 /* The actual error codes are kept in a separate file; see comments
00057    there for the reasons why. */
00058 #include "svn_error_codes.h"
00059 
00063 char *
00064 svn_strerror(apr_status_t statcode,
00065              char *buf,
00066              apr_size_t bufsize);
00067 
00068 
00095 const char *
00096 svn_error_symbolic_name(apr_status_t statcode);
00097 
00098 
00108 const char *svn_err_best_message(svn_error_t *err,
00109                                  char *buf,
00110                                  apr_size_t bufsize);
00111 
00112 
00113 
00138 svn_error_t *
00139 svn_error_create(apr_status_t apr_err,
00140                  svn_error_t *child,
00141                  const char *message);
00142 
00147 svn_error_t *
00148 svn_error_createf(apr_status_t apr_err,
00149                   svn_error_t *child,
00150                   const char *fmt,
00151                   ...)
00152   __attribute__ ((format(printf, 3, 4)));
00153 
00162 svn_error_t *
00163 svn_error_wrap_apr(apr_status_t status,
00164                    const char *fmt,
00165                    ...)
00166        __attribute__((format(printf, 2, 3)));
00167 
00172 svn_error_t *
00173 svn_error_quick_wrap(svn_error_t *child,
00174                      const char *new_msg);
00175 
00187 svn_error_t *
00188 svn_error_compose_create(svn_error_t *err1,
00189                          svn_error_t *err2);
00190 
00199 void
00200 svn_error_compose(svn_error_t *chain,
00201                   svn_error_t *new_err);
00202 
00209 svn_error_t *
00210 svn_error_root_cause(svn_error_t *err);
00211 
00220 svn_error_t *
00221 svn_error_find_cause(svn_error_t *err, apr_status_t apr_err);
00222 
00227 svn_error_t *
00228 svn_error_dup(svn_error_t *err);
00229 
00239 void
00240 svn_error_clear(svn_error_t *error);
00241 
00242 
00243 #if defined(SVN_ERR__TRACING)
00244 
00245 void
00246 svn_error__locate(const char *file,
00247                   long line);
00248 
00249 /* Wrapper macros to collect file and line information */
00250 #define svn_error_create \
00251   (svn_error__locate(__FILE__,__LINE__), (svn_error_create))
00252 #define svn_error_createf \
00253   (svn_error__locate(__FILE__,__LINE__), (svn_error_createf))
00254 #define svn_error_wrap_apr \
00255   (svn_error__locate(__FILE__,__LINE__), (svn_error_wrap_apr))
00256 #define svn_error_quick_wrap \
00257   (svn_error__locate(__FILE__,__LINE__), (svn_error_quick_wrap))
00258 #endif
00259 
00260 
00273 void
00274 svn_handle_error2(svn_error_t *error,
00275                   FILE *stream,
00276                   svn_boolean_t fatal,
00277                   const char *prefix);
00278 
00283 SVN_DEPRECATED
00284 void
00285 svn_handle_error(svn_error_t *error,
00286                  FILE *stream,
00287                  svn_boolean_t fatal);
00288 
00298 void
00299 svn_handle_warning2(FILE *stream,
00300                     svn_error_t *error,
00301                     const char *prefix);
00302 
00307 SVN_DEPRECATED
00308 void
00309 svn_handle_warning(FILE *stream,
00310                    svn_error_t *error);
00311 
00312 
00331 #define SVN_ERR(expr)                           \
00332   do {                                          \
00333     svn_error_t *svn_err__temp = (expr);        \
00334     if (svn_err__temp)                          \
00335       return svn_error_trace(svn_err__temp);    \
00336   } while (0)
00337 
00347 #ifdef SVN_ERR__TRACING
00348 svn_error_t *
00349 svn_error__trace(const char *file, long line, svn_error_t *err);
00350 
00351 #define svn_error_trace(expr)  svn_error__trace(__FILE__, __LINE__, (expr))
00352 #else
00353 #define svn_error_trace(expr)  (expr)
00354 #endif
00355 
00374 svn_error_t *svn_error_purge_tracing(svn_error_t *err);
00375 
00376 
00382 #define SVN_ERR_W(expr, wrap_msg)                           \
00383   do {                                                      \
00384     svn_error_t *svn_err__temp = (expr);                    \
00385     if (svn_err__temp)                                      \
00386       return svn_error_quick_wrap(svn_err__temp, wrap_msg); \
00387   } while (0)
00388 
00389 
00395 #define SVN_INT_ERR(expr)                                        \
00396   do {                                                           \
00397     svn_error_t *svn_err__temp = (expr);                         \
00398     if (svn_err__temp) {                                         \
00399       svn_handle_error2(svn_err__temp, stderr, FALSE, "svn: ");  \
00400       svn_error_clear(svn_err__temp);                            \
00401       return EXIT_FAILURE; }                                     \
00402   } while (0)
00403 
00406 
00422 #define SVN_ERR_IS_LOCK_ERROR(err)                          \
00423   (err->apr_err == SVN_ERR_FS_PATH_ALREADY_LOCKED ||        \
00424    err->apr_err == SVN_ERR_FS_NOT_FOUND           ||        \
00425    err->apr_err == SVN_ERR_FS_OUT_OF_DATE         ||        \
00426    err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN)
00427 
00434 #define SVN_ERR_IS_UNLOCK_ERROR(err)                        \
00435   (err->apr_err == SVN_ERR_FS_PATH_NOT_LOCKED ||            \
00436    err->apr_err == SVN_ERR_FS_BAD_LOCK_TOKEN ||             \
00437    err->apr_err == SVN_ERR_FS_LOCK_OWNER_MISMATCH ||        \
00438    err->apr_err == SVN_ERR_FS_NO_SUCH_LOCK ||               \
00439    err->apr_err == SVN_ERR_RA_NOT_LOCKED ||                 \
00440    err->apr_err == SVN_ERR_FS_LOCK_EXPIRED)
00441 
00448 #define SVN_ERROR_IN_CATEGORY(apr_err, category)            \
00449     ((category) == ((apr_err) / SVN_ERR_CATEGORY_SIZE) * SVN_ERR_CATEGORY_SIZE)
00450 
00451 
00454 
00475 #define SVN_ERR_MALFUNCTION()                                      \
00476   do {                                                             \
00477     return svn_error_trace(svn_error__malfunction(                 \
00478                                  TRUE, __FILE__, __LINE__, NULL)); \
00479   } while (0)
00480 
00488 #define SVN_ERR_MALFUNCTION_NO_RETURN()                      \
00489   do {                                                       \
00490     svn_error__malfunction(FALSE, __FILE__, __LINE__, NULL); \
00491     abort();                                                 \
00492   } while (1)
00493 
00503 #ifdef __clang_analyzer__
00504 #include <assert.h>
00505 /* Just ignore ERR.  If the assert triggers, it'll be our least concern. */
00506 #define SVN_ERR_ASSERT_E(expr, err)       assert((expr))
00507 #else
00508 #define SVN_ERR_ASSERT_E(expr, err)                                      \
00509   do {                                                                  \
00510     if (!(expr)) {                                                      \
00511       return svn_error_compose_create(                                  \
00512                svn_error__malfunction(TRUE, __FILE__, __LINE__, #expr), \
00513                (err));                                                  \
00514     }                                                                   \
00515   } while (0)
00516 #endif
00517 
00518 
00540 #ifdef __clang_analyzer__
00541 #include <assert.h>
00542 #define SVN_ERR_ASSERT(expr)       assert((expr))
00543 #else
00544 #define SVN_ERR_ASSERT(expr)                                            \
00545   do {                                                                  \
00546     if (!(expr))                                                        \
00547       SVN_ERR(svn_error__malfunction(TRUE, __FILE__, __LINE__, #expr)); \
00548   } while (0)
00549 #endif
00550 
00558 #define SVN_ERR_ASSERT_NO_RETURN(expr)                          \
00559   do {                                                          \
00560     if (!(expr)) {                                              \
00561       svn_error__malfunction(FALSE, __FILE__, __LINE__, #expr); \
00562       abort();                                                  \
00563     }                                                           \
00564   } while (0)
00565 
00567 #define SVN__NOT_IMPLEMENTED() \
00568   return svn_error__malfunction(TRUE, __FILE__, __LINE__, "Not implemented.")
00569 
00585 svn_error_t *
00586 svn_error__malfunction(svn_boolean_t can_return,
00587                        const char *file,
00588                        int line,
00589                        const char *expr);
00590 
00612 typedef svn_error_t *(*svn_error_malfunction_handler_t)
00613   (svn_boolean_t can_return, const char *file, int line, const char *expr);
00614 
00626 svn_error_malfunction_handler_t
00627 svn_error_set_malfunction_handler(svn_error_malfunction_handler_t func);
00628 
00637 svn_error_t *
00638 svn_error_raise_on_malfunction(svn_boolean_t can_return,
00639                                const char *file,
00640                                int line,
00641                                const char *expr);
00642 
00649 svn_error_t *
00650 svn_error_abort_on_malfunction(svn_boolean_t can_return,
00651                                const char *file,
00652                                int line,
00653                                const char *expr);
00654 
00658 #ifdef __cplusplus
00659 }
00660 #endif /* __cplusplus */
00661 
00662 #endif /* SVN_ERROR_H */