Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief UBF error handling routines.
0003  *   Also provides functions for general purpose error handling
0004  *   The emulator of UBF library
0005  *   Enduro Execution Library
0006  *
0007  * @file ferror.c
0008  */
0009 /* -----------------------------------------------------------------------------
0010  * Enduro/X Middleware Platform for Distributed Transaction Processing
0011  * Copyright (C) 2009-2016, ATR Baltic, Ltd. All Rights Reserved.
0012  * Copyright (C) 2017-2023, Mavimax, Ltd. All Rights Reserved.
0013  * This software is released under one of the following licenses:
0014  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0015  * See LICENSE file for full text.
0016  * -----------------------------------------------------------------------------
0017  * AGPL license:
0018  *
0019  * This program is free software; you can redistribute it and/or modify it under
0020  * the terms of the GNU Affero General Public License, version 3 as published
0021  * by the Free Software Foundation;
0022  *
0023  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
0024  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0025  * PARTICULAR PURPOSE. See the GNU Affero General Public License, version 3
0026  * for more details.
0027  *
0028  * You should have received a copy of the GNU Affero General Public License along 
0029  * with this program; if not, write to the Free Software Foundation, Inc.,
0030  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0031  *
0032  * -----------------------------------------------------------------------------
0033  * A commercial use license is available from Mavimax, Ltd
0034  * contact@mavimax.com
0035  * -----------------------------------------------------------------------------
0036  */
0037 
0038 /*---------------------------Includes-----------------------------------*/
0039 #include <stdio.h>
0040 #include <stdarg.h>
0041 #include <memory.h>
0042 #include <stdlib.h>
0043 #include <regex.h>
0044 #include <ubf.h>
0045 #include <ubf_int.h>
0046 #include <ndebug.h>
0047 #include <ferror.h>
0048 #include <errno.h>
0049 #include <ubf_tls.h>
0050 
0051 /*---------------------------Externs------------------------------------*/
0052 /*---------------------------Macros-------------------------------------*/
0053 
0054 /**
0055  * Function returns error description
0056  */
0057 #define UBF_ERROR_DESCRIPTION(X) (M_ubf_error_defs[X<BMINVAL?BMINVAL:(X>BMAXVAL?BMAXVAL:X)].msg)
0058 #define UBF_ERROR_CODESTR(X) (M_ubf_error_defs[X<BMINVAL?BMINVAL:(X>BMAXVAL?BMAXVAL:X)].codestr)
0059 
0060 
0061 #define UBFE(X) X,  #X
0062 
0063 /*---------------------------Enums--------------------------------------*/
0064 /*---------------------------Typedefs-----------------------------------*/
0065 /*---------------------------Globals------------------------------------*/
0066 /*---------------------------Statics------------------------------------*/
0067 
0068 /* Do we need this to be in message catalogue?
0069  * table bellow is indexed by id (i.e. direct array erorr lookup should work)
0070  */
0071 struct err_msg
0072 {
0073     int id;
0074     char *codestr;
0075     char *msg;
0076 } M_ubf_error_defs [] =
0077 {
0078     {UBFE(BMINVAL),   "No error"}, /* 0 */
0079     {UBFE(BERFU0),    "BERFU0"}, /* 1 */
0080     {UBFE(BALIGNERR), "Bisubf buffer not aligned"}, /* 2 */
0081     {UBFE(BNOTFLD),   "Buffer not UBF"}, /* 3 */
0082     {UBFE(BNOSPACE),  "No space in UBF buffer"}, /* 4 */
0083     {UBFE(BNOTPRES),  "Field not present"}, /* 5 */
0084     {UBFE(BBADFLD),   "Unknown field number or type"}, /* 6 */
0085     {UBFE(BTYPERR),   "Illegal field type"}, /* 7 */
0086     {UBFE(BEUNIX),    "Unix system call error"}, /* 8 */
0087     {UBFE(BBADNAME),  "Unknown field name"}, /* 9 */
0088     {UBFE(BMALLOC),   "Malloc failed"}, /* 10 */
0089     {UBFE(BSYNTAX),   "Bad syntax in boolean expression"}, /* 11 */
0090     {UBFE(BFTOPEN),   "Cannot find or open field table"}, /* 12 */
0091     {UBFE(BFTSYNTAX), "Syntax error in field table"}, /* 13 */
0092     {UBFE(BEINVAL),   "Invalid argument to function"}, /* 14 */
0093     {UBFE(BERFU1),    "BERFU1"}, /* 15 */
0094     {UBFE(BBADTBL),   "Bad access to field table"}, /* 16 */
0095     {UBFE(BBADVIEW),  "Bad view name/not loaded"}, /* 17 */
0096     {UBFE(BVFSYNTAX), "View file syntax error"}, /* 18 */
0097     {UBFE(BVFOPEN),   "Failed to open view file"}, /* 19 */
0098     {UBFE(BBADACM),   "View array count indicator negative"}, /* 20 */
0099     {UBFE(BNOCNAME),  "Structure field (cname) not found"},
0100     {UBFE(BEBADOP),  "Bad operation"}, /* 21 */
0101 };
0102 /*---------------------------Prototypes---------------------------------*/
0103 
0104 /**
0105  * Return error code in string format
0106  * note in case of invalid error code, the max or min values will be returned.
0107  * @param err error code
0108  * @return ptr to constant string (error code)
0109  */
0110 expublic char * Becodestr(int err)
0111 {
0112     return UBF_ERROR_CODESTR(err);
0113 }
0114 /**
0115  * Standard.
0116  * Printer error to stderr
0117  * @param str
0118  */
0119 expublic void B_error (char *str)
0120 {
0121     UBF_TLS_ENTRY;
0122     if (EXEOS!=G_ubf_tls->M_ubf_error_msg_buf[0])
0123     {
0124         fprintf(stderr, "%s:%d:%s (%s)\n", str, G_ubf_tls->M_ubf_error, 
0125                 UBF_ERROR_DESCRIPTION(G_ubf_tls->M_ubf_error),
0126                 G_ubf_tls->M_ubf_error_msg_buf);
0127     }
0128     else
0129     {
0130         fprintf(stderr, "%s:%d:%s\n", str, G_ubf_tls->M_ubf_error, 
0131                 UBF_ERROR_DESCRIPTION(G_ubf_tls->M_ubf_error));
0132     }
0133 }
0134 
0135 /**
0136  * Extended version. This will print internal error message what happened.
0137  * This is not thread safe (as all other functions).
0138  * @param error_code
0139  */
0140 expublic char * Bstrerror (int err)
0141 {
0142     UBF_TLS_ENTRY;
0143 
0144     if (EXEOS!=G_ubf_tls->M_ubf_error_msg_buf[0])
0145     {
0146         snprintf(G_ubf_tls->errbuf, sizeof(G_ubf_tls->errbuf), 
0147                 "%d:%s (last error %d: %s)",
0148                 err,
0149                 UBF_ERROR_DESCRIPTION(err),
0150                 G_ubf_tls->M_ubf_error,
0151                 G_ubf_tls->M_ubf_error_msg_buf);
0152     }
0153     else
0154     {
0155         snprintf(G_ubf_tls->errbuf, sizeof(G_ubf_tls->errbuf), "%d:%s",
0156                             err, UBF_ERROR_DESCRIPTION(err));
0157     }
0158 
0159     return G_ubf_tls->errbuf;
0160 }
0161 
0162 /**
0163  * ATMI standard
0164  * @return - pointer to int holding error code?
0165  */
0166 expublic int * ndrx_Bget_Ferror_addr (void)
0167 {
0168     UBF_TLS_ENTRY;
0169     return &G_ubf_tls->M_ubf_error;
0170 }
0171 
0172 /**
0173  * For ABI compatiblity with older Enduro/X versions.
0174  */
0175 expublic int * _Bget_Ferror_addr (void)
0176 {
0177     return ndrx_Bget_Ferror_addr();
0178 }
0179 
0180 /**
0181  * Internetal function for setting
0182  * @param error_code
0183  * @param msg
0184  * @return
0185  */
0186 expublic void ndrx_Bset_error(int error_code)
0187 {
0188     UBF_TLS_ENTRY;
0189     if (!G_ubf_tls->M_ubf_error)
0190     {
0191         UBF_LOG(log_warn, "%s: %d (%s)", __func__,
0192                                 error_code, UBF_ERROR_DESCRIPTION(error_code));
0193         G_ubf_tls->M_ubf_error_msg_buf[0] = EXEOS;
0194         G_ubf_tls->M_ubf_error = error_code;
0195     }
0196 }
0197 
0198 /**
0199  * I nternetal function for setting
0200  * @param error_code
0201  * @param msg
0202  * @return
0203  */
0204 expublic void ndrx_Bset_error_msg(int error_code, char *msg)
0205 {
0206     int msg_len;
0207     int err_len;
0208 
0209     UBF_TLS_ENTRY;
0210     
0211     if (!G_ubf_tls->M_ubf_error)
0212     {
0213         msg_len = strlen(msg);
0214         err_len = (msg_len>MAX_ERROR_LEN)?MAX_ERROR_LEN:msg_len;
0215 
0216 
0217         UBF_LOG(log_warn, "%s: %d (%s) [%s]", __func__, error_code,
0218                                 UBF_ERROR_DESCRIPTION(error_code), msg);
0219         G_ubf_tls->M_ubf_error_msg_buf[0] = EXEOS;
0220         strncat(G_ubf_tls->M_ubf_error_msg_buf, msg, err_len);
0221         G_ubf_tls->M_ubf_error = error_code;
0222     }
0223 }
0224 
0225 /**
0226  * Advanced error setting function, uses format list
0227  * Use this only in case where it is really needed.
0228  * @param error_code - error code
0229  * @param fmt - format stirng
0230  * @param ... - format details
0231  */
0232 expublic void ndrx_Bset_error_fmt(int error_code, const char *fmt, ...)
0233 {
0234     char msg[MAX_ERROR_LEN+1] = {EXEOS};
0235     va_list ap;
0236     UBF_TLS_ENTRY;
0237     
0238     if (!G_ubf_tls->M_ubf_error)
0239     {
0240         va_start(ap, fmt);
0241         (void) vsnprintf(msg, sizeof(msg), fmt, ap);
0242         va_end(ap);
0243 
0244         NDRX_STRCPY_SAFE(G_ubf_tls->M_ubf_error_msg_buf, msg);
0245         G_ubf_tls->M_ubf_error = error_code;
0246 
0247         UBF_LOG(log_warn, "%s: %d (%s) [%s]", __func__,
0248                         error_code, UBF_ERROR_DESCRIPTION(error_code),
0249                         G_ubf_tls->M_ubf_error_msg_buf);
0250     }
0251 }
0252 
0253 /**
0254  * Unset any error data currently in use
0255  */
0256 expublic void ndrx_Bunset_error(void)
0257 {
0258     UBF_TLS_ENTRY;
0259     G_ubf_tls->M_ubf_error_msg_buf[0]=EXEOS;
0260     G_ubf_tls->M_ubf_error = BMINVAL;
0261 }
0262 /**
0263  * Return >0 if error is set
0264  * @return 
0265  */
0266 expublic int ndrx_Bis_error(void)
0267 {
0268     UBF_TLS_ENTRY;
0269     return G_ubf_tls->M_ubf_error;
0270 }
0271 
0272 /**
0273  * Append error message
0274  * @param msg
0275  */
0276 expublic void ndrx_Bappend_error_msg(char *msg)
0277 {
0278     int free_space;
0279     int app_error_len = strlen(msg);
0280     int n;
0281     UBF_TLS_ENTRY;
0282     
0283     free_space = MAX_ERROR_LEN-strlen(G_ubf_tls->M_ubf_error_msg_buf);
0284     n = free_space<app_error_len?free_space:app_error_len;
0285     strncat(G_ubf_tls->M_ubf_error_msg_buf, msg, n);
0286 }
0287 
0288 /**
0289  * Report regular expression error.
0290  * @param fun_nm
0291  * @param err
0292  * @param rp
0293  */
0294 expublic void ndrx_report_regexp_error(char *fun_nm, int err, regex_t *rp)
0295 {
0296     char *errmsg;
0297     int errlen;
0298     char errbuf[2048];
0299     errlen = (int) regerror(err, rp, NULL, 0);
0300     errmsg = (char *) NDRX_MALLOC(errlen*sizeof(char));
0301     regerror(err, rp, errmsg, errlen);
0302 
0303     snprintf(errbuf, sizeof(errbuf), "regexp err (%s, %d, \"%s\").",
0304                                         fun_nm, err, errmsg);
0305     UBF_LOG(log_error, "Failed to compile regexp: [%s]", errbuf);
0306     ndrx_Bset_error_msg(BSYNTAX, errbuf);
0307 
0308     NDRX_FREE(errmsg);
0309 }
0310 
0311 /**
0312  * Save current error
0313  * @param p_err
0314  */
0315 expublic void ndrx_Bsave_error(ndrx_ubf_error_t *p_err)
0316 {
0317     UBF_TLS_ENTRY;
0318     
0319     p_err->ubf_error = G_ubf_tls->M_ubf_error;
0320     NDRX_STRCPY_SAFE(p_err->ubf_error_msg_buf, G_ubf_tls->M_ubf_error_msg_buf);
0321 }
0322 
0323 /**
0324  * Restore current error
0325  * @param p_err
0326  */
0327 expublic void ndrx_Brestore_error(ndrx_ubf_error_t *p_err)
0328 {
0329     UBF_TLS_ENTRY;
0330     G_ubf_tls->M_ubf_error = p_err->ubf_error;
0331     NDRX_STRCPY_SAFE(G_ubf_tls->M_ubf_error_msg_buf, p_err->ubf_error_msg_buf);
0332 }
0333 
0334 /* vim: set ts=4 sw=4 et smartindent: */