dberr.c

来自「db.* (pronounced dee-be star) is an adva」· C语言 代码 · 共 248 行

C
248
字号
/*************************************************************************** *                                                                         * * db.*                                                                    * * open source database kernel                                             * *                                                                         * * Copyright (c) 2000 Centura Software Corporation. All rights reserved.   * *                                                                         * * Use of this software, whether in source code format, or in executable,  * * binary object code form, is governed by the CENTURA OPEN SOURCE LICENSE * * which is fully described in the LICENSE.TXT file, included within this  * * distribution of source code files.                                      *  *                                                                         * **************************************************************************/#include "db.star.h"#include "rntmint.h"#if !defined(NO_ERRSTR)#include "dberr.h"#endif/* ======================================================================    Database auto-recovery notification function*/void INTERNAL_FCN dbautorec(DB_TASK *task){    /* Call dberr to display "recovery about to occur" message,       and flush the error, otherwise it won't appear till after       recovery is complete, when the d_ function returns.    */    dberr(S_RECOVERY);    flush_dberr(task);    task->errnum = task->db_status = S_OKAY;}/* ======================================================================    Signal database error*/int EXTERNAL_FCN _dberr(int errnum, char *filename, int linenum, DB_TASK *task){    if (errnum >= S_OKAY)    {        /* don't overwrite a previous error */        if (task->db_status >= 0)            task->db_status = errnum;        return errnum;    }    /* S_RECFAIL is returned when an auto-recovery fails. The failure       must be caused by some other error, such as an I/O error, so it       is likely that db_status is already set. Report the previous       error before storing the S_RECFAIL code.    */    if (errnum == S_RECFAIL)        flush_dberr(task);    /* don't overwrite a previous error */    if (task->db_status < 0)        return errnum;    /* S_REENTER is returned when db.* is called reentrantly with the       same task argument - could happen if the application's database       error handler calls a d_ function. To avoid infinite recursion,       this error is not reported through the error handler.    */    if (errnum == S_REENTER)        return (task->db_status = errnum);       if (!task->errnum)    {        /* save the error state */        if ((errnum <= S_INTERNAL_FIRST) && (errnum >= S_INTERNAL_LAST))        {            task->err_ex = errnum;            errnum = S_SYSERR;        }        task->errnum  = errnum;        task->errno_c = psp_errno();        task->errfile = filename;        task->errline = linenum;    }    return (task->db_status = errnum);}/* ======================================================================*/void EXTERNAL_FCN flush_dberr(DB_TASK *task){    ERRORPROC fn = task->error_func;    DB_TCHAR msg_string[180];    if (task->errnum >= 0)        return;    /* generate error message string */    dberr_msg(msg_string, sizeof(msg_string) / sizeof(DB_TCHAR), task);#ifdef DB_TRACE    if (task->db_trace)    {        /* log the error to the trace file */        db_printf(task, DB_TEXT("%s\n"), msg_string);    }#endif    /* The db.* runtime guards against reentrancy during the dberr callback.       You can check for reentrancy restrictions within the callback by        checking the return value from a call to d_dberr(S_OKAY, task).       Return Value   Handler Restrictions       ------------   ------------------------------------------------------       S_OKAY         It is safe to perform a non-local goto (throw or                      longjmp), and you may call any d_ function using the                      current task.       S_REENTER      The handler must not call any d_ functions except                      d_closetask using the current task - all attempts will                      return S_REENTER.  d_closetask is available to force                      close the task, but the handler _must_ throw or longjmp                      or else it will be repeatedly called with S_INVTASK.       Note:  it is always safe for the handler to call d_ functions for       another task.    */    if (fn)    {        int inDBSTAR = task->inDBSTAR;        fn(task->errnum, msg_string);        /* sanity check - make sure the task was not freed! */        if (inDBSTAR && (ntask_check(task) < 0))        {            errstring(msg_string, S_INVTASK, sizeof(msg_string));            for (;;) fn(S_INVTASK, msg_string); // only way out is non-local goto        }    }    else  /* default error handler */        psp_errPrint(msg_string);}/* ======================================================================    Construct an error message string    (note: this may be called during db_exit() after task is no longer     accessible)*/void EXTERNAL_FCN dberr_msg(    DB_TCHAR *msg_string,    int msg_len,    DB_TASK *task){    DB_STRING msg;#define MESSAGE_LEN  80    DB_TCHAR msgbuf[MESSAGE_LEN];    DB_TCHAR *msg_type;    DB_TCHAR errstr[10];    int stat;    if (task->errnum >= 0)    {        msg_type = DB_TEXT("Function Status Code");        vtstrcpy(msgbuf, DB_TEXT(""));    }    else if (task->errnum == S_LMCERROR)    {        msg_type = DB_TEXT("LMC error");        stat = psp_lmcErrstr(msgbuf, task->err_ex, MESSAGE_LEN, task->lmc);        if (stat != S_OKAY)            errstring(msgbuf, stat, MESSAGE_LEN);    }    else if ((task->errnum <= S_USER_FIRST) && (task->errnum >= S_USER_LAST))    {        msg_type = DB_TEXT("PROGRAMMER/USER error");        errstring(msgbuf, task->errnum, MESSAGE_LEN);    }    else if (task->errnum == S_SYSERR)    {        msg_type = DB_TEXT("INTERNAL error");        errstring(msgbuf, task->err_ex ? task->err_ex : S_SYSERR, MESSAGE_LEN);    }    else if ((task->errnum <= S_SYSTEM_FIRST) && (task->errnum >= S_SYSTEM_LAST))    {        msg_type = DB_TEXT("SYSTEM/OS error");        errstring(msgbuf, task->errnum, MESSAGE_LEN);    }    else    {        msg_type = DB_TEXT("INTERNAL error");        vstprintf(msgbuf, DB_TEXT("Unrecognized error %d"), task->errnum);    }    msgbuf[MESSAGE_LEN-1] = DB_TEXT('\0');    /* just in case */    /* Message format:            +-------------------------+            | type: errnum            |            | errmsg                  |            | C errno = nn: strerror  |            | FILE: filename(linenum) |            | DLL: dll_name           |            +-------------------------+    */    msg_string[0] = DB_TEXT('\0');    STRinit(&msg, msg_string, msg_len);    STRcpy(&msg, msg_type);    vstprintf(errstr, DB_TEXT(": %d\n"), task->errnum);    STRcat(&msg, errstr);    STRcat(&msg, msgbuf);    vstprintf(msgbuf, DB_TEXT("\nC errno = %d"), task->errno_c);    STRcat(&msg, msgbuf);    vstprintf(msgbuf, DB_TEXT(": ") DB_STRFMT, strerror(task->errno_c));    STRcat(&msg, msgbuf);    if (task->errfile != NULL && task->errline != 0)    {        vstprintf(msgbuf, DB_TEXT("\nFILE: ") DB_STRFMT DB_TEXT("(%d)"),                task->errfile, task->errline);        STRcat(&msg, msgbuf);    }}/* ======================================================================    Return error message string for specified error number*/int INTERNAL_FCN errstring(DB_TCHAR *msgbuf, int errnum, int buflen){    DB_TCHAR *msg = NULL;#if defined(NO_ERRSTR)    if (errnum == S_RECOVERY)        msg = DB_TEXT("automatic recovery about to occur");    else        msg = DB_TEXT("error message unavailable");#else    if (errnum <= S_USER_FIRST && errnum >= S_USER_LAST)        msg = user_error[S_USER_FIRST - errnum];    else if (errnum <= S_SYSTEM_FIRST && errnum >= S_SYSTEM_LAST)        msg = system_error[S_SYSTEM_FIRST - errnum];    else if (errnum <= S_INTERNAL_FIRST && errnum >= S_INTERNAL_LAST)        msg = internal_error[S_INTERNAL_FIRST - errnum];#endif    if (msg)        vstrnzcpy(msgbuf, msg, buflen);    return S_OKAY;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?