#ifdef RCSID static char RCSid[] = "$Header: d:/cvsroot/tads/TADS2/ERR.C,v 1.2 1999/05/17 02:52:11 MJRoberts Exp $"; #endif /* * Copyright (c) 1991, 2002 Michael J. Roberts. All Rights Reserved. * * Please see the accompanying license file, LICENSE.TXT, for information * on using and copying this software. */ /* Name err.c - error handling functions Function Functions for error signalling and recovery Notes None Modified 10/02/91 MJRoberts - creation */ #include #include "os.h" #include "err.h" #include "tok.h" /* format an error message, sprintf-style, using an erradef array */ int errfmt(outbuf, outbufl, fmt, argc, argv) char *outbuf; int outbufl; char *fmt; int argc; erradef *argv; { int outlen = 0; int argi = 0; int len; char buf[20]; char *p; char fmtchar; while (*fmt) { switch(*fmt) { case '\\': ++fmt; len = 1; switch(*fmt) { case '\0': --fmt; break; case '\n': p = "\n"; break; case '\t': p = "\t"; break; default: p = fmt; break; } break; case '%': ++fmt; fmtchar = *fmt; if (argi >= argc) fmtchar = 1; /* too many - ignore it */ switch(fmtchar) { case '\0': --fmt; break; case '%': p = "%"; len = 1; break; case 'd': sprintf(buf, "%d", argv[argi].erraint); len = strlen(buf); p = buf; break; case 's': p = argv[argi].errastr; len = strlen(p); break; case 't': { int i; static struct { int tokid; char *toknam; } toklist[] = { { TOKTSEM, "semicolon" }, { TOKTCOLON, "colon" }, { TOKTFUNCTION, "\"function\"" }, { TOKTCOMMA, "comma" }, { TOKTLBRACE, "left brace ('{')" }, { TOKTRPAR, "right paren (')')" }, { TOKTRBRACK, "right square bracket (']')" }, { TOKTWHILE, "\"while\"" }, { TOKTLPAR, "left paren ('(')" }, { TOKTEQ, "'='" }, { 0, (char *)0 } }; for (i = 0 ; toklist[i].toknam ; ++i) { if (toklist[i].tokid == argv[argi].erraint) { p = toklist[i].toknam; break; } } if (!toklist[i].toknam) p = ""; len = strlen(p); break; } default: p = ""; len = 0; --argi; break; } ++argi; break; default: p = fmt; len = 1; break; } /* copy output that was set up above */ if (len) { if (outbufl >= len) { memcpy(outbuf, p, (size_t)len); outbufl -= len; outbuf += len; } else if (outbufl) { memcpy(outbuf, p, (size_t)outbufl); outbufl = 0; } outlen += len; } ++fmt; } if (outbufl) *outbuf++ = '\0'; return(outlen); } #ifdef DEBUG void errjmp(buf, e) jmp_buf buf; int e; { longjmp(buf, e); } #endif /* DEBUG */ #ifdef ERR_NO_MACRO /* base error signal function */ void errsign(ctx, e) errcxdef *ctx; int e; { ctx->errcxofs = 0; longjmp(ctx->errcxptr->errbuf, e); } /* signal an error with no arguments */ void errsig(ctx, e) errcxdef *ctx; int e; { errargc(ctx, 0); errsign(ctx, e); } /* enter a string argument */ char *errstr(ctx, str, len) errcxdef *ctx; char *str; int len; { char *ret = &ctx->errcxbuf[ctx->errcxofs]; memcpy(ret, str, (size_t)len); ret[len] = '\0'; ctx->errcxofs += len + 1; return(ret); } /* resignal current error */ void errrse1(ctx, fr) errcxdef *ctx; errdef *fr; { errargc(ctx, fr->erraac); memcpy(ctx->errcxptr->erraav, fr->erraav, (size_t)(fr->erraac * sizeof(erradef))); errsign(ctx, fr->errcode); } /* log an error: base function */ void errlogn(ctx, err) errcxdef *ctx; int err; { ctx->errcxofs = 0; (*ctx->errcxlog)(ctx->errcxlgc, err, ctx->errcxptr->erraac, ctx->errcxptr->erraav); } /* log an error with no arguments */ void errlog(ctx, err) errcxdef *ctx; int err; { errargc(ctx, 0); errlogn(ctx, err); } #endif /* ERR_NO_MACRO */