da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1985-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Glenn Fowler <gsf@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Phong Vo <kpv@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Glenn Fowler
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Research
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * error and message formatter
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * level is the error level
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * level >= error_info.core!=0 dumps core
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * level >= ERROR_FATAL calls error_info.exit
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * level < 0 is for debug tracing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NOTE: id && ERROR_NOID && !ERROR_USAGE implies format=id for errmsg()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * 2007-03-19 move error_info from _error_info_ to (*_error_infop_)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * to allow future Error_info_t growth
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * by 2009 _error_info_ can be static
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define extern extern __EXPORT__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,0,0,0,0,0,0,0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0, /* version */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0, /* auxilliary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,0,0,0,0,0,0, /* top of old context stack */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,0,0,0,0,0,0, /* old empty context */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0, /* time */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0 /* catalog */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * these should probably be in error_info
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called by stropt() to set options
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinsetopt(void* a, const void* p, register int n, register const char* v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (*v)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((error_state.match || (error_state.match = newof(0, regex_t, 1, 0))) && regcomp(error_state.match, v, REG_EXTENDED|REG_LENIENT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print a name with optional delimiter, converting unprintable chars
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinprint(register Sfio_t* sp, register char* name, char* delim)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *name++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c & 0200)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c &= 0177;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (c = *name++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c & 0200)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c &= 0177;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c < ' ')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print error context FIFO stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CONTEXT(f,p) (((f)&ERROR_PUSH)?((Error_context_t*)&(p)->context->context):((Error_context_t*)(p)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chincontext(register Sfio_t* sp, register Error_context_t* cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sp, ": \"%s\", %s %d", cp->file, ERROR_translate(NiL, NiL, ast.id, "line"), cp->line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * debugging breakpoint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (error_state.tty || (error_state.tty = sfopen(NiL, "/dev/tty", "r+")))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stropt(getenv("ERROR_OPTIONS"), options, sizeof(*options), setopt, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if ((library = strchr(catalog, ':')) && !*++library)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 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))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = (flags & ERROR_OUTPUT) ? va_arg(ap, int) : error_info.fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "Usage"));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (file || opt_info.argv && (file = opt_info.argv[0]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin context(stkstd, CONTEXT(error_info.flags, error_info.context));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin print(stkstd, file, (flags & ERROR_LIBRARY) ? " " : ": ");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin catalog ? catalog : ERROR_translate(NiL, NiL, ast.id, "DEFAULT"),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (level > 0 && error_info.line > ((flags & ERROR_INTERACTIVE) != 0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd, "%s %d: ", ERROR_translate(NiL, NiL, ast.id, "line"), error_info.line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((d = times(&us)) < error_info.time || error_info.time == 1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd, " %05lu.%05lu.%05lu ", d - error_info.time, (unsigned long)us.tms_utime, (unsigned long)us.tms_stime);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "warning"));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd, "%s: ", ERROR_translate(NiL, NiL, ast.id, "panic"));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd, "%s%d:%s", s, level, level > -10 ? " " : "");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * source ([version], file, line) message
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(stkstd, "(%s: \"%s\", %s %d) ", error_info.version, file, s, line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * level&ERROR_OUTPUT on return means message
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * already output
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((flags & ERROR_SYSTEM) && errno && errno != error_info.last_errno)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin level = (*error_info.auxilliary)(stkstd, level, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n -= ++t - s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if HUH_19980401 /* nasty problems if sfgetr() is in effect! */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fd == sffileno(sfstderr) && error_info.write == write)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 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))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * error_info context control