main index

section index




/*-------------------------------------------------------------*/
typedef enum {
  NETWIB_ERR_ENCODETYPE_TEXT = 1,    /* append the error text */
  NETWIB_ERR_ENCODETYPE_NUMTEXT,     /* append "Error n : text" */
  NETWIB_ERR_ENCODETYPE_FULL         /* full (error, errno, h_errno,
                                        GetLastError, errstr) :
                                        "Error n : text\n `--> message\n"
                                     */
} netwib_err_encodetype;

/*-------------------------------------------------------------*/
/* Name : netwib_buf_append_err
   Description :
     Append a string representing an error.
   Input parameter(s) :
     error : error to print
     encodetype : netwib_err_encodetype to use
   Input/output parameter(s) :
   Output parameter(s) :
     *pbuf : netwib_buf receiving data
   Normal return values :
     NETWIB_ERR_OK : ok
   Notes :
     - Error code might have been set by a previous error. By
       example, error in open() sets errno, and then an error
       is gethostbyname() sets h_errno, and both will be
       displayed because the first one is not purged.
       This is normal, because if user directly used
       gethostbyname(), he knows he doesn't have to look at
        errno.
     - If an error occurred in function open() and sets errno.
       Then, memory might need to be freed (so errno will be
       unset). Then error is returned to user, but errno is
       zero.
    As a conclusion, user might not_get/get_incorrect errno,
    h_errno or GetLastError.
*/
netwib_err netwib_buf_append_err(netwib_err error,
                                 netwib_err_encodetype encodetype,
                                 netwib_buf *buf);

/*-------------------------------------------------------------*/
/* Name : netwib_err_display
   Description :
     Print the error associated to a netwib_err.
   Input parameter(s) :
     error : error to print
     encodetype : netwib_err_encodetype to use
   Input/output parameter(s) :
   Output parameter(s) :
   Normal return values :
     NETWIB_ERR_OK : ok
*/
netwib_err netwib_err_display(netwib_err error,
                              netwib_err_encodetype encodetype);

/*-------------------------------------------------------------*/
/***************************************************************
 * Every netwib function return an netwib_err corresponding to *
 * an error code. Developer have to test this value to ensure  *
 * everything went fine. There is 3 ways to do it :            *
 *                                                             *
 *  1 - doing the test by hand :                               *
 *    ret = function(...);                                     *
 *    if (ret != NETWIB_ERR_OK) {                              *
 *      return(ret);                                           *
 *    }                                                        *
 *                                                             *
 *  2 - use netwib_er :                                        *
 *    netwib_er(function(...));                                *
 *                                                             *
 *  3 - use netwib_eg :                                        *
 *    Note : this define uses a "goto". Developers tend to     *
 *           hate using goto. I also do, but there is one case *
 *           where goto are very useful. This case is for      *
 *           error handling because it creates an error flow   *
 *           similar to exceptions in Java or C++.             *
 *           I'll try to explain it : a program has two flows  *
 *           inside : the normal flow (the real job done) and  *
 *           the error flow (what to do when an error occurs). *
 *           With most algorithms, both flow use the same path,*
 *           so there is no need to use goto. But, when flow   *
 *           differs, we have to complicate the algorithm to   *
 *           deal with both normal and errors conditions.      *
 *           Without goto, it quickly becomes hard to read     *
 *           code, to free (only allocated) resources, to close*
 *           (only opened) descriptors, etc.                   *
 *           With goto, we have something like :               *
 *    {
 *      netwib_io *pio1, *pio2, *pio3;
 *      netwib_bool pio1set, pio2set, pio3set;
 *      netwib_err ret;
 *
 *      pio1set = pio2set = pio3set = NETWIB_FALSE;
 *      ret = NETWIB_ERR_OK;
 *
 *      netwib_eg(netwib_io_init...(&pio1));
 *      pio1set = NETWIB_TRUE;
 *      netwib_eg(netwib_io_init...(&pio2));
 *      pio2set = NETWIB_TRUE;
 *      here_complicated_code_which_can_use_"netwib_eg()"
 *      netwib_eg(netwib_io_close(&pio2));
 *      pio2set = NETWIB_FALSE;
 *      here_complicated_code_which_can_use_"netwib_eg()"
 *      netwib_eg(netwib_io_init...(&pio3));
 *      pio3set = NETWIB_TRUE;
 *
 *     netwib_gotolabel :
 *      if (pio1set) { netwib_er(netwib_io_close(&pio1)); }
 *      if (pio2set) { netwib_er(netwib_io_close(&pio2)); }
 *      if (pio3set) { netwib_er(netwib_io_close(&pio3)); }
 *      return(ret);
 *    }
 *           As seen in this simple example, program flow and  *
 *           error flow are separated.                         *
 ***************************************************************/

/* if (r != NETWIB_ERR_OK) return(r) */
#define netwib_er(r) {netwib_err netwib_coderr=r;if(netwib_coderr!=NETWIB_ERR_OK)return(netwib_coderr);}

/* the label */
#define netwib_gotolabel netwibleavefunction

/* goto label and return r (note : this uses a variable named "ret") */
#define netwib_goto(r) {ret = r; goto netwibleavefunction;}

/* if (r != NETWIB_ERR_OK) { goto label and return r } */
#define netwib_eg(r) {netwib_err netwib_coderr=r;if(netwib_coderr!=NETWIB_ERR_OK)netwib_goto(netwib_coderr);}







main index

section index