/* * error.c * * Summary: Exception handling functions. * * Author: David Hardy */ #include #include #include #include "error.h" int mdio_warn(const char *fmt, ...) { int ret; va_list v; va_start(v, fmt); ret = fprintf(stderr, "MDIO WARNING: "); ret += vfprintf(stderr, fmt, v); va_end(v); return ret; } int mdio_error(const char *fmt, ...) { int ret; va_list v; va_start(v, fmt); ret = fprintf(stderr, "MDIO ERROR: "); ret += vfprintf(stderr, fmt, v); va_end(v); return ret; } void mdio_fatal(const char *fmt, ...) { va_list v; va_start(v, fmt); (void) fprintf(stderr, "MDIO FATAL ERROR: "); (void) vfprintf(stderr, fmt, v); va_end(v); exit(-1); } static const char *ERRMSG[] = { /* form: 0x________ */ "status OK", /* 0x0 */ "unknown token from input file", /* 0x1 */ "non-terminated comment from input file", /* 0x2 */ "truncated line from input file", /* 0x4 */ "unused", /* 0x8 */ "unused", /* 0x10 */ "unused", /* 0x20 */ "unused", /* 0x40 */ "unused", /* 0x80 */ "unused", /* 0x100 */ "unused", /* 0x200 */ "unused", /* 0x400 */ "illegal format from input file", /* 0x800 */ "cannot allocate memory", /* 0x1000 */ "cannot open file", /* 0x2000 */ "cannot close file", /* 0x4000 */ "cannot read from file", /* 0x8000 */ "cannot write to file", /* 0x10000 */ "unsupported feature", /* 0x20000 */ "unused", /* 0x40000 */ "unused", /* 0x80000 */ "unused", /* 0x100000 */ "unused", /* 0x200000 */ "unused", /* 0x400000 */ "unused", /* 0x800000 */ "unused", /* 0x1000000 */ "unused", /* 0x2000000 */ "unused", /* 0x4000000 */ "unused", /* 0x8000000 */ "unused", /* 0x10000000 */ "unused", /* 0x20000000 */ "unused", /* 0x40000000 */ "" }; /* * unfortunately, this function isn't thread safe */ const char *mdio_errmsg(int status) { static char errmsg[2560]; /* == 32 * 80, more space than we actually need */ int k, chkbit; char *p = errmsg; const char *q; if (status < 0) { return "status number out of range"; } else if (status == 0) { return ERRMSG[0]; } else { for (k = 1, chkbit = 1; ; k++, chkbit <<= 1) { MDIO_ASSERT(k < 32 && chkbit > 0); if (chkbit & status) { for (q = ERRMSG[k]; (*p = *q) != '\0'; p++, q++) ; /* fast strcat */ status ^= chkbit; /* clear bits as we check them */ if (status == 0) break; *p++ = ','; *p++ = ' '; /* strcat ", " on end */ } } return (const char *) errmsg; } } #if defined(MDIO_TEST) || defined(MDIO_MODULE_TEST) /* define functions used to test module */ int error_test(void) { /* check out all status messages individually */ mdio_warn("%s\n", mdio_errmsg(MDIO_WARN_UNKNOWN)); mdio_warn("%s\n", mdio_errmsg(MDIO_WARN_COMMENT)); mdio_warn("%s\n", mdio_errmsg(MDIO_WARN_TRUNC)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_LEVEL)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_FORMAT)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_MEMALLOC)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_OPEN)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_CLOSE)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_READ)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_WRITE)); mdio_error("%s\n", mdio_errmsg(MDIO_ERR_UNSUPPORTED)); /* now check them out all ORed together */ mdio_fatal("%s\n", mdio_errmsg(MDIO_WARN_UNKNOWN | MDIO_WARN_COMMENT | MDIO_WARN_TRUNC | MDIO_ERR_LEVEL | MDIO_ERR_FORMAT | MDIO_ERR_MEMALLOC | MDIO_ERR_OPEN | MDIO_ERR_CLOSE | MDIO_ERR_READ | MDIO_ERR_WRITE | MDIO_ERR_UNSUPPORTED)); /* this statement is not reached */ return 0; } #endif #if defined(MDIO_MODULE_TEST) /* define main() to test this module */ int main(void) { (void) error_test(); return 0; } #endif