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