/* AppExceptions
 *
 * A category of Application that provides methods for mapping
 * ASCII names to integers for use in NeXTSTEP exception handling.
 *
 * Copyright 1991, 1992 Scott Hess.  This source code may be
 * redistributed and modified without restriction.  Well, one
 * restriction - do not claim that you wrote it.
 *
 * Scott Hess
 * 12901 Upton Avenue South, #326
 * Burnsville, MN  55337
 * (612) 895-1208
 * scott@gac.edu
 * shess@ssesco.com
 */
#import "AppExceptions.h"
#import <appkit/errors.h>
#import <objc/HashTable.h>

@implementation Application (AppExceptions)
int appExceptionsReference=0;
	/* Hash exception names to numbers. */
static HashTable *exceptionTable=nil;
	/* Base for building exceptions. */
static int exceptionBase=NX_APPBASE;
	/* Reports errors for our exceptions. */
static void errorReporter( NXHandler *h)
{
    const char *name=[NXApp nameForException:h->code];
    if( name) {
	fprintf( stderr, "Uncaught exception %s==%d.\n", name, h->code);
    } else {
	fprintf( stderr, "Unknown exception %d.\n", h->code);
    }
}
-(int)exceptionFor:(const char *)name
{
    if( !name) {
	int exception;
	if( !exceptionTable) {
	    exceptionTable=[[HashTable alloc] initKeyDesc:"*" valueDesc:"i" capacity:32];
	    NXRegisterErrorReporter( NX_APPBASE, NX_APPBASE+999, errorReporter);
	}
	exception=(int)[exceptionTable valueForKey:name];
	if( !exception) {
	    exception=exceptionBase++;
	    [exceptionTable insertKey:name value:(void *)exception];
	}
	return exception;
    }
    return -1;
}
-(const char *)nameForException:(int)exception
{
    const char *key;
    int value;
    NXHashState state=[exceptionTable initState];
    while( [exceptionTable nextState:&state key:(const void **)&key
					  value:(void **)&value]) {
	if( exception==value) {
	    return key;
	}
    }
    return NULL;
}
- raiseException:(const char *)name with:(const void *)data1 with:(const void *)data2
{
    NX_RAISE( [self exceptionFor:name], data1, data2);
}
- raiseException:(const char *)name with:(const void *)data1
{
    return [self raiseException:name with:data1 with:NULL];
}
- raiseException:(const char *)name
{
    return [self raiseException:name with:NULL with:NULL];
}

@end
