edt_error.c

Go to the documentation of this file.
00001 
00009 #include "edt_utils.h"
00010 #include "edt_error.h"
00011 
00012 #include <stdlib.h>
00013 #include <string.h>
00014 
00015 #include <stdarg.h>
00016 
00017 #ifdef WIN32
00018 
00019 #include <windows.h>
00020 #include <process.h>
00021 
00022 #else
00023 
00024 #ifndef VXWORKS
00025 #include <sys/errno.h>
00026 #endif
00027 
00028 #endif
00029 
00030 
00031 
00032 #define MAX_MESSAGE 512
00033 
00034 
00035 #define EDT_DEFAULT_MSG_LEVEL     \
00036     EDTAPP_MSG_FATAL \
00037     | EDTAPP_MSG_WARNING \
00038     | EDTLIB_MSG_FATAL \
00039     | EDTLIB_MSG_WARNING \
00040     | PDVLIB_MSG_FATAL \
00041     | PDVLIB_MSG_WARNING \
00042     | EDT_MSG_ALWAYS
00043 
00044 
00045 static char edt_last_error_message[MAX_MESSAGE];
00046 
00047 EdtMsgHandler edt_default_msg;
00048 static int edt_default_msg_initialized = 0;
00049 
00050 static int 
00051 edt_msg_printf(void *f_p, int level,  const char *message)
00052 {
00053     FILE *f = (FILE *) f_p;
00054 
00055 
00056     if (f)
00057         return fprintf(f, "%s", message);
00058 
00059     else
00060         return -1;
00061 
00062 }
00063 
00064 static void 
00065 edt_msg_close_file(EdtMsgHandler *msg_p)
00066 
00067 {
00068     if (msg_p->own_file && msg_p->file)
00069         fclose(msg_p->file);
00070 
00071     if (msg_p->target == msg_p->file)
00072         msg_p->target = NULL;
00073 
00074     msg_p->file = NULL;
00075     msg_p->own_file = 0;
00076 
00077 }
00078 
00079 
00080 /* copied from libedt.c, so we don't need to link to that just for this function
00081 */
00082 static unsigned 
00083 edt_err_num(void)
00084 {
00085 #ifdef _NT_
00086     return GetLastError();
00087 #else 
00088     extern int errno;
00089     return errno;
00090 #endif
00091 }
00092 
00093 static int
00094 edt_msg_output_vprintf_perror(EdtMsgHandler *msg_p,  int level, const char *format, va_list ap)
00095 {
00096 
00097     char *fullmsg; /* callers message + perror message */
00098     int success = -1;
00099     /* copy of last errno so no problem if it changes while executing this func. */
00100     unsigned error = edt_err_num(); 
00101 
00102 #ifdef _NT_
00103     LPVOID *  lpMsgBuf;
00104 #else
00105     char *errstr; /* perror message */
00106     extern int errno;
00107 #endif
00108 
00109     if (msg_p == &edt_default_msg)
00110     {
00111         if (!edt_default_msg_initialized)
00112             edt_msg_init(msg_p);
00113     }
00114 
00115     if (!(level & msg_p->level))
00116         return 0;
00117 
00118 
00119     /* get caller's string...  */ 
00120 
00121     vsprintf(edt_last_error_message, format, ap);
00122 
00123     /* ... then add system error string to it. */
00124 #ifdef _NT_
00125 
00126     FormatMessage(
00127         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00128         NULL,
00129         error,
00130         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),      /* Default language */
00131         (LPTSTR) & lpMsgBuf,
00132         0,
00133         NULL
00134         );
00135     /* add three for \n and ": " chars. */
00136     fullmsg = (char *)malloc(strlen(edt_last_error_message) + strlen( (char*)lpMsgBuf ) + 3*sizeof(char) +1);
00137     sprintf(fullmsg, "%s: %s\n", edt_last_error_message, (char*)lpMsgBuf);
00138     LocalFree(lpMsgBuf);
00139 #else
00140     errstr = strerror(error);
00141     /* add three for \n and ": " chars. */
00142     fullmsg = (char *)malloc(strlen(edt_last_error_message) + strlen(errstr) + 3*sizeof(char));
00143     sprintf(fullmsg, "%s: %s\n", edt_last_error_message, errstr);
00144 #endif
00145 
00146 
00147     if (msg_p->func) {
00148         success = msg_p->func(msg_p->target, level, fullmsg);
00149     }
00150 
00151     free(fullmsg);
00152     return success;
00153 }
00154 
00155 
00156 
00173 void 
00174 edt_msg_init(EdtMsgHandler *msg_p)
00175 
00176 {
00177     if (msg_p)
00178     {
00179         msg_p->file = stderr;
00180         msg_p->own_file = 0;
00181         msg_p->level = EDT_DEFAULT_MSG_LEVEL;
00182         msg_p->func = edt_msg_printf;
00183         msg_p->target = msg_p->file;
00184     }
00185 
00186     if (msg_p == &edt_default_msg)
00187         edt_default_msg_initialized = 1;
00188 }
00189 
00190 
00200 void 
00201 edt_msg_init_names(EdtMsgHandler *msg_p, char *file, int level)
00202 
00203 {
00204     edt_msg_init(msg_p);
00205     edt_msg_set_name(msg_p, file);
00206     edt_msg_set_level(msg_p, level);
00207 
00208 }
00209 
00220 void 
00221 edt_msg_init_files(EdtMsgHandler *msg_p, FILE *file, int level)
00222 
00223 {
00224     edt_msg_init(msg_p);
00225     edt_msg_set_file(msg_p, file);
00226     edt_msg_set_level(msg_p, level);
00227 }
00228 
00229 
00230 
00245 void 
00246 edt_msg_close(EdtMsgHandler *msg_p)
00247 
00248 {
00249     edt_msg_close_file(msg_p);
00250 }
00251 
00252 
00253 
00278 int
00279 edt_msg(int level, const char *format, ...)
00280 {
00281     va_list     stack;
00282 
00283     if (!edt_default_msg_initialized)
00284         edt_msg_init(&edt_default_msg);
00285 
00286     if (!(level & edt_default_msg.level))
00287         return 0;
00288 
00289     va_start(stack,     format);
00290 
00291     vsprintf(edt_last_error_message, format, stack);
00292 
00293     if (edt_default_msg.func)
00294         return edt_default_msg.func(edt_default_msg.target, level, edt_last_error_message);
00295     return -1;
00296 
00297 }
00298 
00299 
00300 
00343 int
00344 edt_msg_output(EdtMsgHandler *msg_p,  int level, const char *format, ...)
00345 {
00346 
00347     va_list     stack;
00348 
00349 
00350     if (msg_p == &edt_default_msg)
00351     {
00352         if (!edt_default_msg_initialized)
00353             edt_msg_init(msg_p);
00354     }
00355 
00356     if (!(level & msg_p->level))
00357         return 0;
00358 
00359     va_start(stack,     format);
00360 
00361     vsprintf(edt_last_error_message, format, stack);
00362 
00363     if (msg_p->func)
00364         return msg_p->func(msg_p->target, level, edt_last_error_message);
00365 
00366     return -1;
00367 }
00368 
00369 
00370 
00371 
00388 void 
00389 edt_msg_set_level(EdtMsgHandler *msg_p, int newlevel)
00390 
00391 {
00392     if ((msg_p == &edt_default_msg) && !edt_default_msg_initialized)
00393         edt_msg_init(&edt_default_msg);
00394 
00395     msg_p->level  = newlevel;
00396 
00397 }
00398 
00406 int 
00407 edt_msg_get_level(EdtMsgHandler *msg_p) 
00408 {
00409     return msg_p->level;
00410 }
00411 
00412 
00420 void 
00421 edt_msg_add_level(EdtMsgHandler *msg_p, int level) 
00422 {
00423     edt_msg_set_level(msg_p, edt_msg_get_level(msg_p) | level);
00424 }
00425 
00426 
00440 void 
00441 edt_msg_set_function(EdtMsgHandler *msg_p, EdtMsgFunction f)
00442 
00443 {
00444     if ((msg_p == &edt_default_msg) && !edt_default_msg_initialized)
00445         edt_msg_init(&edt_default_msg);
00446 
00447     msg_p->func = f;
00448 }
00449 
00476 void 
00477 edt_msg_set_file(EdtMsgHandler *msg_p, FILE *fp)
00478 
00479 {
00480     if ((msg_p == &edt_default_msg) && !edt_default_msg_initialized)
00481         edt_msg_init(&edt_default_msg);
00482 
00483     edt_msg_close_file(msg_p);
00484 
00485     msg_p->file = fp; 
00486 
00487     msg_p->own_file = 0;
00488 }
00489 
00490 
00498 void 
00499 edt_msg_set_name(EdtMsgHandler *msg_p, const char *name)
00500 
00501 {
00502     if ((msg_p == &edt_default_msg) && !edt_default_msg_initialized)
00503         edt_msg_init(&edt_default_msg);
00504 
00505     edt_msg_close_file(msg_p);
00506 
00507     msg_p->file = fopen(name, "wb");
00508 
00509     msg_p->own_file = (msg_p->file != NULL);
00510     edt_msg_set_target(msg_p, msg_p->file);
00511 
00512 }
00513 
00523 void 
00524 edt_msg_set_target(EdtMsgHandler *msg_p, void *target)
00525 
00526 {
00527     if ((msg_p == &edt_default_msg) && !edt_default_msg_initialized)
00528         edt_msg_init(&edt_default_msg);
00529 
00530     msg_p->target = target;
00531 }
00532 
00533 
00553 int
00554 edt_msg_perror(int level, const char *msg)
00555 
00556 {
00558     char message[MAX_MESSAGE];
00559 
00560 #ifdef _NT_
00561     LPVOID *  lpMsgBuf;
00562 #else
00563     extern int errno;
00564 #endif
00565 
00566     if (!edt_default_msg_initialized)
00567         edt_msg_init(&edt_default_msg);
00568 
00569     if (!(level & edt_default_msg.level))
00570         return 0;
00571 
00572 #ifdef _NT_
00573 
00574     FormatMessage(
00575         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00576         NULL,
00577         GetLastError(),
00578         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),      /* Default language */
00579         (LPTSTR) & lpMsgBuf,
00580         0,
00581         NULL
00582         );
00583 
00584     sprintf(message, "%s: %s\n", msg, lpMsgBuf);
00585     LocalFree(lpMsgBuf);
00586 #else
00587     sprintf(message, "%s: %s\n", msg, strerror(errno));
00588 #endif
00589     return edt_msg(level, message);
00590 }
00591 
00592 
00605 int
00606 edt_msg_output_perror(EdtMsgHandler *msg_p, int level, const char *msg)
00607 
00608 {
00609     char message[MAX_MESSAGE];
00610 
00611 #ifdef _NT_
00612     LPVOID *  lpMsgBuf;
00613 #else
00614     extern int errno;
00615 #endif
00616 
00617     if ((msg_p == &edt_default_msg) && !edt_default_msg_initialized)
00618         edt_msg_init(&edt_default_msg);
00619 
00620 #ifdef _NT_
00621 
00622     FormatMessage(
00623         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00624         NULL,
00625         GetLastError(),
00626         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),      /* Default language */
00627         (LPTSTR) & lpMsgBuf,
00628         0,
00629         NULL
00630         );
00631 
00632     sprintf(message, "%s: %s\n", msg, lpMsgBuf);
00633     LocalFree(lpMsgBuf);
00634 #else
00635     sprintf(message, "%s: %s\n", msg, strerror(errno));
00636 #endif
00637 
00638     return edt_msg_printf(msg_p->target, level, message);
00639 }
00640 
00672 int 
00673 edt_msg_printf_perror(int level, const char *format, ...)
00674 {
00675     va_list stack;
00676     va_start(stack, format);
00677 
00678     return edt_msg_output_vprintf_perror(&edt_default_msg, level, format, stack);
00679 }
00680 
00681 
00698 int
00699 edt_msg_output_printf_perror(EdtMsgHandler *msg_p,  int level, const char *format, ...)
00700 {
00701     va_list stack;
00702     va_start(stack, format);
00703 
00704     return edt_msg_output_vprintf_perror(msg_p, level, format, stack);
00705 }
00706 
00707 
00715 EdtMsgHandler *
00716 edt_msg_default_handle()
00717 {
00718     if (!edt_default_msg_initialized)
00719         edt_msg_init(&edt_default_msg);
00720 
00721     return &edt_default_msg;
00722 }
00723 
00732 int
00733 edt_msg_default_level()
00734 {
00735     if (!edt_default_msg_initialized)
00736         edt_msg_init(&edt_default_msg);
00737 
00738     return edt_default_msg.level;
00739 }
00740 
00741 
00746 char *edt_msg_last_error()
00747 {
00748     return edt_last_error_message;
00749 }
00750 
00751 static int lvl_indent = 0;
00752 
00753 int
00754 lvl_printf(int delta, char *format, ...)
00755 {
00756     va_list     stack;
00757     int i;
00758     char message[512];
00759     va_start(stack,     format);
00760 
00761     if (delta < 0)
00762         lvl_indent += delta;
00763 
00764     for (i=0;i<lvl_indent;i++)
00765         printf("    ");
00766 
00767     vsprintf(message, format, stack);
00768 
00769     printf("%s",message);
00770     if (delta > 0)
00771         lvl_indent += delta;
00772 
00773     return lvl_indent;
00774 }
00775 
00776 /*
00777 * output message simplified - levels 0 - 3
00778 * level 0 - fatal only
00779 * level 1 - warnings
00780 * level 2 - info level 1
00781 * level 3 - info level 2
00782 */
00783 
00784 void
00785 edt_set_verbosity(int verbose)
00786 
00787 {
00788     int level = edt_msg_default_level();
00789     if (verbose < 1)
00790         level = 0;
00791     else if (verbose > 1) /* default is slightly verbose */
00792     {
00793         level |= EDTAPP_MSG_INFO_1;
00794         level |= EDTLIB_MSG_INFO_1;
00795     }
00796     if (verbose > 2)
00797     {
00798         level |= EDTAPP_MSG_INFO_1
00799             | EDTAPP_MSG_INFO_2
00800             | EDTLIB_MSG_INFO_1
00801             | EDTLIB_MSG_INFO_2;
00802     }
00803     edt_msg_set_level(edt_msg_default_handle(), level);
00804 }
00805 
00806 int
00807 edt_get_verbosity()
00808 
00809 {
00810     if (edt_default_msg.level & (EDTAPP_MSG_INFO_2 | EDTLIB_MSG_INFO_2))
00811         return 3;
00812     if (edt_default_msg.level & (EDTAPP_MSG_INFO_1 | EDTLIB_MSG_INFO_1))
00813         return 2;
00814     if (edt_default_msg.level & (EDT_DEFAULT_MSG_LEVEL))
00815         return 1;
00816 
00817     return 0;
00818 
00819 }
00820 

Generated on 19 Jun 2015 by  doxygen 1.4.7