ref: 6bc6badcb6768cd559431f139d13c7b9e5ef16ed
dir: /error.c/
#include <u.h>
#include <libc.h>
#include <thread.h>
#include "dat.h"
#include "fns.h"
static ErrorCtx *
errorctx(void)
{
/* Return a pointer to the current error context.
* TODO: think about what needs its own context
*/
static ErrorCtx *c = nil;
if(c == nil)
c = alloc(DataErrorCtx);
return c;
}
ErrorTrap *
setuptrap(int n, ...)
{
ErrorCtx *c = errorctx();
c->count++;
c->traps = allocextra(c, sizeof(*c->traps) * c->count);
ErrorTrap *t = alloc(DataErrorTrap);
va_list nums;
va_start(nums, n);
for(; n > 0; n--){
int x = va_arg(nums, int);
assert(x >= EAny && x <= ErrorMax);
if(x == EAny){
for(int i = 0; i < ErrorMax; i++)
t->nums[i] = 1;
}else
t->nums[x] = 1;
}
va_end(nums);
c->traps[c->count-1] = t;
return t;
}
void
endtrap(void)
{
ErrorCtx *c = errorctx();
c->count--;
}
char *
errmsg(void)
{
ErrorCtx *c = errorctx();
return c->msg;
}
char *
errdesc(void)
{
ErrorCtx *c = errorctx();
switch(c->num){
case ESyntax: return "SYNTAX ERROR";
case EValue: return "VALUE ERROR";
case EInternal: return "INTERNAL ERROR";
case EDomain: return "DOMAIN ERROR";
default: return "ERROR ???";
}
}
_Noreturn void
error(int num, char *fmt, ...)
{
ErrorCtx *c;
ErrorTrap *t;
va_list args;
va_start(args, fmt);
c = errorctx();
c->num = num;
vsnprint(c->msg, sizeof(c->msg), fmt, args);
while(1){
assert(c->count > 0);
c->count--;
t = c->traps[c->count];
if(t->nums[num])
longjmp(t->env, 1);
}
}