diff options
Diffstat (limited to 'usr/src/lib/libast/common/misc/error.c')
-rw-r--r-- | usr/src/lib/libast/common/misc/error.c | 659 |
1 files changed, 0 insertions, 659 deletions
diff --git a/usr/src/lib/libast/common/misc/error.c b/usr/src/lib/libast/common/misc/error.c deleted file mode 100644 index cf7c015084..0000000000 --- a/usr/src/lib/libast/common/misc/error.c +++ /dev/null @@ -1,659 +0,0 @@ -/*********************************************************************** -* * -* This software is part of the ast package * -* Copyright (c) 1985-2010 AT&T Intellectual Property * -* and is licensed under the * -* Common Public License, Version 1.0 * -* by AT&T Intellectual Property * -* * -* A copy of the License is available at * -* http://www.opensource.org/licenses/cpl1.0.txt * -* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * -* * -* Information and Software Systems Research * -* AT&T Research * -* Florham Park NJ * -* * -* Glenn Fowler <gsf@research.att.com> * -* David Korn <dgk@research.att.com> * -* Phong Vo <kpv@research.att.com> * -* * -***********************************************************************/ -#pragma prototyped -/* - * Glenn Fowler - * AT&T Research - * - * error and message formatter - * - * level is the error level - * level >= error_info.core!=0 dumps core - * level >= ERROR_FATAL calls error_info.exit - * level < 0 is for debug tracing - * - * NOTE: id && ERROR_NOID && !ERROR_USAGE implies format=id for errmsg() - */ - -#include "lclib.h" - -#include <ctype.h> -#include <ccode.h> -#include <namval.h> -#include <sig.h> -#include <stk.h> -#include <times.h> -#include <regex.h> - -/* - * 2007-03-19 move error_info from _error_info_ to (*_error_infop_) - * to allow future Error_info_t growth - * by 2009 _error_info_ can be static - */ - -#if _BLD_ast && defined(__EXPORT__) -#define extern extern __EXPORT__ -#endif - -extern Error_info_t _error_info_; - -Error_info_t _error_info_ = -{ - 2, exit, write, - 0,0,0,0,0,0,0,0, - 0, /* version */ - 0, /* auxilliary */ - 0,0,0,0,0,0,0, /* top of old context stack */ - 0,0,0,0,0,0,0, /* old empty context */ - 0, /* time */ - translate, - 0 /* catalog */ -}; - -#undef extern - -__EXTERN__(Error_info_t, _error_info_); - -__EXTERN__(Error_info_t*, _error_infop_); - -Error_info_t* _error_infop_ = &_error_info_; - -/* - * these should probably be in error_info - */ - -static struct State_s -{ - char* prefix; - Sfio_t* tty; - unsigned long count; - int breakpoint; - regex_t* match; -} error_state; - -#undef ERROR_CATALOG -#define ERROR_CATALOG (ERROR_LIBRARY<<1) - -#define OPT_BREAK 1 -#define OPT_CATALOG 2 -#define OPT_CORE 3 -#define OPT_COUNT 4 -#define OPT_FD 5 -#define OPT_LIBRARY 6 -#define OPT_MASK 7 -#define OPT_MATCH 8 -#define OPT_PREFIX 9 -#define OPT_SYSTEM 10 -#define OPT_TIME 11 -#define OPT_TRACE 12 - -static const Namval_t options[] = -{ - "break", OPT_BREAK, - "catalog", OPT_CATALOG, - "core", OPT_CORE, - "count", OPT_COUNT, - "debug", OPT_TRACE, - "fd", OPT_FD, - "library", OPT_LIBRARY, - "mask", OPT_MASK, - "match", OPT_MATCH, - "prefix", OPT_PREFIX, - "system", OPT_SYSTEM, - "time", OPT_TIME, - "trace", OPT_TRACE, - 0, 0 -}; - -/* - * called by stropt() to set options - */ - -static int -setopt(void* a, const void* p, register int n, register const char* v) -{ - NoP(a); - if (p) - switch (((Namval_t*)p)->value) - { - case OPT_BREAK: - case OPT_CORE: - if (n) - switch (*v) - { - case 'e': - case 'E': - error_state.breakpoint = ERROR_ERROR; - break; - case 'f': - case 'F': - error_state.breakpoint = ERROR_FATAL; - break; - case 'p': - case 'P': - error_state.breakpoint = ERROR_PANIC; - break; - default: - error_state.breakpoint = strtol(v, NiL, 0); - break; - } - else - error_state.breakpoint = 0; - if (((Namval_t*)p)->value == OPT_CORE) - error_info.core = error_state.breakpoint; - break; - case OPT_CATALOG: - if (n) - error_info.set |= ERROR_CATALOG; - else - error_info.clear |= ERROR_CATALOG; - break; - case OPT_COUNT: - if (n) - error_state.count = strtol(v, NiL, 0); - else - error_state.count = 0; - break; - case OPT_FD: - error_info.fd = n ? strtol(v, NiL, 0) : -1; - break; - case OPT_LIBRARY: - if (n) - error_info.set |= ERROR_LIBRARY; - else - error_info.clear |= ERROR_LIBRARY; - break; - case OPT_MASK: - if (n) - error_info.mask = strtol(v, NiL, 0); - else - error_info.mask = 0; - break; - case OPT_MATCH: - if (error_state.match) - regfree(error_state.match); - if (n) - { - if ((error_state.match || (error_state.match = newof(0, regex_t, 1, 0))) && regcomp(error_state.match, v, REG_EXTENDED|REG_LENIENT)) - { - free(error_state.match); - error_state.match = 0; - } - } - else if (error_state.match) - { - free(error_state.match); - error_state.match = 0; - } - break; - case OPT_PREFIX: - if (n) - error_state.prefix = strdup(v); - else if (error_state.prefix) - { - free(error_state.prefix); - error_state.prefix = 0; - } - break; - case OPT_SYSTEM: - if (n) - error_info.set |= ERROR_SYSTEM; - else - error_info.clear |= ERROR_SYSTEM; - break; - case OPT_TIME: - error_info.time = n ? 1 : 0; - break; - case OPT_TRACE: - if (n) - error_info.trace = -strtol(v, NiL, 0); - else - error_info.trace = 0; - break; - } - return 0; -} - -/* - * print a name with optional delimiter, converting unprintable chars - */ - -static void -print(register Sfio_t* sp, register char* name, char* delim) -{ - if (mbwide()) - sfputr(sp, name, -1); - else - { -#if CC_NATIVE != CC_ASCII - register int c; - register unsigned char* n2a; - register unsigned char* a2n; - register int aa; - register int as; - - n2a = ccmap(CC_NATIVE, CC_ASCII); - a2n = ccmap(CC_ASCII, CC_NATIVE); - aa = n2a['A']; - as = n2a[' ']; - while (c = *name++) - { - c = n2a[c]; - if (c & 0200) - { - c &= 0177; - sfputc(sp, '?'); - } - if (c < as) - { - c += aa - 1; - sfputc(sp, '^'); - } - c = a2n[c]; - sfputc(sp, c); - } -#else - register int c; - - while (c = *name++) - { - if (c & 0200) - { - c &= 0177; - sfputc(sp, '?'); - } - if (c < ' ') - { - c += 'A' - 1; - sfputc(sp, '^'); - } - sfputc(sp, c); - } -#endif - } - if (delim) - sfputr(sp, delim, -1); -} - -/* - * print error context FIFO stack - */ - -#define CONTEXT(f,p) (((f)&ERROR_PUSH)?((Error_context_t*)&(p)->context->context):((Error_context_t*)(p))) - -static void -context(register Sfio_t* sp, register Error_context_t* cp) -{ - if (cp->context) - context(sp, CONTEXT(cp->flags, cp->context)); - if (!(cp->flags & ERROR_SILENT)) - { - if (cp->id) - print(sp, cp->id, NiL); - if (cp->line > ((cp->flags & ERROR_INTERACTIVE) != 0)) - { - if (cp->file) - sfprintf(sp, ": \"%s\", %s %d", cp->file, ERROR_translate(NiL, NiL, ast.id, "line"), cp->line); - else - sfprintf(sp, "[%d]", cp->line); - } - sfputr(sp, ": ", -1); - } -} - -/* - * debugging breakpoint - */ - -extern void -error_break(void) -{ - char* s; - - if (error_state.tty || (error_state.tty = sfopen(NiL, "/dev/tty", "r+"))) - { - sfprintf(error_state.tty, "error breakpoint: "); - if (s = sfgetr(error_state.tty, '\n', 1)) - { - if (streq(s, "q") || streq(s, "quit")) - exit(0); - stropt(s, options, sizeof(*options), setopt, NiL); - } - } -} - -void -error(int level, ...) -{ - va_list ap; - - va_start(ap, level); - errorv(NiL, level, ap); - va_end(ap); -} - -void -errorv(const char* id, int level, va_list ap) -{ - register int n; - int fd; - int flags; - char* s; - char* t; - char* format; - char* library; - const char* catalog; - - int line; - char* file; - -#if !_PACKAGE_astsa - unsigned long d; - struct tms us; -#endif - - if (!error_info.init) - { - error_info.init = 1; - stropt(getenv("ERROR_OPTIONS"), options, sizeof(*options), setopt, NiL); - } - if (level > 0) - { - flags = level & ~ERROR_LEVEL; - level &= ERROR_LEVEL; - } - else - flags = 0; - if ((flags & (ERROR_USAGE|ERROR_NOID)) == ERROR_NOID) - { - format = (char*)id; - id = 0; - } - else - format = 0; - if (id) - { - catalog = (char*)id; - if (!*catalog || *catalog == ':') - { - catalog = 0; - library = 0; - } - else if ((library = strchr(catalog, ':')) && !*++library) - library = 0; - } - else - { - catalog = 0; - library = 0; - } - if (catalog) - id = 0; - else - { - id = (const char*)error_info.id; - catalog = error_info.catalog; - } - if (level < error_info.trace || (flags & ERROR_LIBRARY) && !(((error_info.set | error_info.flags) ^ error_info.clear) & ERROR_LIBRARY) || level < 0 && error_info.mask && !(error_info.mask & (1<<(-level - 1)))) - { - if (level >= ERROR_FATAL) - (*error_info.exit)(level - 1); - return; - } - if (error_info.trace < 0) - flags |= ERROR_LIBRARY|ERROR_SYSTEM; - flags |= error_info.set | error_info.flags; - flags &= ~error_info.clear; - if (!library) - flags &= ~ERROR_LIBRARY; - fd = (flags & ERROR_OUTPUT) ? va_arg(ap, int) : error_info.fd; - if (error_info.write) - { - long off; - char* bas; - - bas = stkptr(stkstd, 0); - if (off = stktell(stkstd)) - stkfreeze(stkstd, 0); - file = error_info.id; - if (error_state.prefix) - sfprintf(stkstd, "%s: ", error_state.prefix); - if (flags & ERROR_USAGE) - { - if (flags & ERROR_NOID) - sfprintf(stkstd, " "); - else - sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "Usage")); - if (file || opt_info.argv && (file = opt_info.argv[0])) - print(stkstd, file, " "); - } - else - { - if (level && !(flags & ERROR_NOID)) - { - if (error_info.context && level > 0) - context(stkstd, CONTEXT(error_info.flags, error_info.context)); - if (file) - print(stkstd, file, (flags & ERROR_LIBRARY) ? " " : ": "); - if (flags & (ERROR_CATALOG|ERROR_LIBRARY)) - { - sfprintf(stkstd, "["); - if (flags & ERROR_CATALOG) - sfprintf(stkstd, "%s %s%s", - catalog ? catalog : ERROR_translate(NiL, NiL, ast.id, "DEFAULT"), - ERROR_translate(NiL, NiL, ast.id, "catalog"), - (flags & ERROR_LIBRARY) ? ", " : ""); - if (flags & ERROR_LIBRARY) - sfprintf(stkstd, "%s %s", - library, - ERROR_translate(NiL, NiL, ast.id, "library")); - sfprintf(stkstd, "]: "); - } - } - if (level > 0 && error_info.line > ((flags & ERROR_INTERACTIVE) != 0)) - { - if (error_info.file && *error_info.file) - sfprintf(stkstd, "\"%s\", ", error_info.file); - sfprintf(stkstd, "%s %d: ", ERROR_translate(NiL, NiL, ast.id, "line"), error_info.line); - } - } -#if !_PACKAGE_astsa - if (error_info.time) - { - if ((d = times(&us)) < error_info.time || error_info.time == 1) - error_info.time = d; - sfprintf(stkstd, " %05lu.%05lu.%05lu ", d - error_info.time, (unsigned long)us.tms_utime, (unsigned long)us.tms_stime); - } -#endif - switch (level) - { - case 0: - flags &= ~ERROR_SYSTEM; - break; - case ERROR_WARNING: - sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "warning")); - break; - case ERROR_PANIC: - sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "panic")); - break; - default: - if (level < 0) - { - s = ERROR_translate(NiL, NiL, ast.id, "debug"); - if (error_info.trace < -1) - sfprintf(stkstd, "%s%d:%s", s, level, level > -10 ? " " : ""); - else - sfprintf(stkstd, "%s: ", s); - for (n = 0; n < error_info.indent; n++) - { - sfputc(stkstd, ' '); - sfputc(stkstd, ' '); - } - } - break; - } - if (flags & ERROR_SOURCE) - { - /* - * source ([version], file, line) message - */ - - file = va_arg(ap, char*); - line = va_arg(ap, int); - s = ERROR_translate(NiL, NiL, ast.id, "line"); - if (error_info.version) - sfprintf(stkstd, "(%s: \"%s\", %s %d) ", error_info.version, file, s, line); - else - sfprintf(stkstd, "(\"%s\", %s %d) ", file, s, line); - } - if (format || (format = va_arg(ap, char*))) - { - if (!(flags & ERROR_USAGE)) - format = ERROR_translate(NiL, id, catalog, format); - sfvprintf(stkstd, format, ap); - } - if (!(flags & ERROR_PROMPT)) - { - /* - * level&ERROR_OUTPUT on return means message - * already output - */ - - if ((flags & ERROR_SYSTEM) && errno && errno != error_info.last_errno) - { - sfprintf(stkstd, " [%s]", fmterror(errno)); - if (error_info.set & ERROR_SYSTEM) - errno = 0; - error_info.last_errno = (level >= 0) ? 0 : errno; - } - if (error_info.auxilliary && level >= 0) - level = (*error_info.auxilliary)(stkstd, level, flags); - sfputc(stkstd, '\n'); - } - if (level > 0) - { - if ((level & ~ERROR_OUTPUT) > 1) - error_info.errors++; - else - error_info.warnings++; - } - if (level < 0 || !(level & ERROR_OUTPUT)) - { - n = stktell(stkstd); - s = stkptr(stkstd, 0); - if (t = memchr(s, '\f', n)) - { - n -= ++t - s; - s = t; - } -#if HUH_19980401 /* nasty problems if sfgetr() is in effect! */ - sfsync(sfstdin); -#endif - sfsync(sfstdout); - sfsync(sfstderr); - if (fd == sffileno(sfstderr) && error_info.write == write) - { - sfwrite(sfstderr, s, n); - sfsync(sfstderr); - } - else - (*error_info.write)(fd, s, n); - } - else - { - s = 0; - level &= ERROR_LEVEL; - } - stkset(stkstd, bas, off); - } - else - s = 0; - if (level >= error_state.breakpoint && error_state.breakpoint && (!error_state.match || !regexec(error_state.match, s ? s : format, 0, NiL, 0)) && (!error_state.count || !--error_state.count)) - { - if (error_info.core) - { -#ifndef SIGABRT -#ifdef SIGQUIT -#define SIGABRT SIGQUIT -#else -#ifdef SIGIOT -#define SIGABRT SIGIOT -#endif -#endif -#endif -#ifdef SIGABRT - signal(SIGABRT, SIG_DFL); - kill(getpid(), SIGABRT); - pause(); -#else - abort(); -#endif - } - else - error_break(); - } - if (level >= ERROR_FATAL) - (*error_info.exit)(level - ERROR_FATAL + 1); -} - -/* - * error_info context control - */ - -static Error_info_t* freecontext; - -Error_info_t* -errorctx(Error_info_t* p, int op, int flags) -{ - if (op & ERROR_POP) - { - if (!(_error_infop_ = p->context)) - _error_infop_ = &_error_info_; - if (op & ERROR_FREE) - { - p->context = freecontext; - freecontext = p; - } - p = _error_infop_; - } - else - { - if (!p) - { - if (p = freecontext) - freecontext = freecontext->context; - else if (!(p = newof(0, Error_info_t, 1, 0))) - return 0; - *p = *_error_infop_; - p->errors = p->flags = p->line = p->warnings = 0; - p->catalog = p->file = 0; - } - if (op & ERROR_PUSH) - { - p->flags = flags; - p->context = _error_infop_; - _error_infop_ = p; - } - p->flags |= ERROR_PUSH; - } - return p; -} |