/* GNU Objective C Runtime archiving
- Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
Contributed by Kresten Krab Thorup
This file is part of GNU CC.
#define PTR2LONG(P) (((char*)(P))-(char*)0)
#define LONG2PTR(L) (((char*)0)+(L))
-#define __objc_fatal(format, args...) \
- { fprintf(stderr, "archiving: "); \
- fprintf(stderr, format, ## args); \
- fprintf(stderr, "\n"); abort(); }
-
/* Declare some functions... */
static int
return (*stream->write)(stream->physical, &buf, 1);
}
else
- abort();
+ objc_error(nil, OBJC_ERR_BAD_OPCODE,
+ "__objc_write_extension: bad opcode %c\n", code);
}
__inline__ int
{
int len;
if (stream->writing_root_p)
- __objc_fatal ("objc_write_root_object called recursively")
+ objc_error (nil, OBJC_ERR_RECURSE_ROOT,
+ "objc_write_root_object called recursively");
else
{
stream->writing_root_p = 1;
}
else
- __objc_fatal("expected 8bit signed int, got %dbit int",
- (int)(buf&_B_NUMBER)*8);
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected 8bit signed int, got %dbit int",
+ (int)(buf&_B_NUMBER)*8);
}
return len;
}
len = (*stream->read)(stream->physical, val, 1);
else
- __objc_fatal("expected 8bit unsigned int, got %dbit int",
- (int)(buf&_B_NUMBER)*8);
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected 8bit unsigned int, got %dbit int",
+ (int)(buf&_B_NUMBER)*8);
}
return len;
}
int pos = 1;
int nbytes = buf[0] & _B_NUMBER;
if (nbytes > sizeof (short))
- __objc_fatal("expected short, got bigger (%dbits)", nbytes*8);
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected short, got bigger (%dbits)", nbytes*8);
len = (*stream->read)(stream->physical, buf+1, nbytes);
(*value) = 0;
while (pos <= nbytes)
int pos = 1;
int nbytes = buf[0] & _B_NUMBER;
if (nbytes > sizeof (short))
- __objc_fatal("expected short, got int or bigger");
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected short, got int or bigger");
len = (*stream->read)(stream->physical, buf+1, nbytes);
(*value) = 0;
while (pos <= nbytes)
int pos = 1;
int nbytes = buf[0] & _B_NUMBER;
if (nbytes > sizeof (int))
- __objc_fatal("expected int, got bigger");
+ objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger");
len = (*stream->read)(stream->physical, buf+1, nbytes);
(*value) = 0;
while (pos <= nbytes)
int pos = 1;
int nbytes = buf[0] & _B_NUMBER;
if (nbytes > sizeof (long))
- __objc_fatal("expected long, got bigger");
+ objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger");
len = (*stream->read)(stream->physical, buf+1, nbytes);
(*value) = 0;
while (pos <= nbytes)
unsigned char buf[sizeof(unsigned int)+1];
if (nbytes > sizeof (int))
- __objc_fatal("expected int, got bigger");
+ objc_error(nil, OBJC_ERR_BAD_DATA, "expected int, got bigger");
len = (*stream->read)(stream->physical, buf, nbytes);
(*val) = 0;
unsigned char buf[sizeof(unsigned long)+1];
if (nbytes > sizeof (long))
- __objc_fatal("expected long, got bigger");
+ objc_error(nil, OBJC_ERR_BAD_DATA, "expected long, got bigger");
len = (*stream->read)(stream->physical, buf, nbytes);
(*val) = 0;
break;
default:
- __objc_fatal("expected string, got opcode %c\n", (buf[0]&_B_CODE));
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected string, got opcode %c\n", (buf[0]&_B_CODE));
}
}
/* check null-byte */
len = (*stream->read)(stream->physical, buf, 1);
if (buf[0] != '\0')
- __objc_fatal("expected null-byte, got opcode %c", buf[0]);
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected null-byte, got opcode %c", buf[0]);
}
else if ((buf[0]&_B_CODE) == _B_UCOMM)
{
if (key)
- __objc_fatal("cannot register use upcode...");
+ objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode...");
len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key);
(*object) = hash_value_for_key (stream->object_table, LONG2PTR(key));
}
else if (buf[0] == (_B_EXT | _BX_OBJROOT)) /* a root object */
{
if (key)
- __objc_fatal("cannot register root object...");
+ objc_error(nil, OBJC_ERR_BAD_KEY,
+ "cannot register root object...");
len = objc_read_object (stream, object);
__objc_finish_read_root_object (stream);
}
else
- __objc_fatal("expected object, got opcode %c", buf[0]);
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected object, got opcode %c", buf[0]);
}
return len;
}
else if ((buf[0]&_B_CODE) == _B_UCOMM)
{
if (key)
- __objc_fatal("cannot register use upcode...");
+ objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode...");
len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key);
(*class) = hash_value_for_key (stream->stream_table, LONG2PTR(key));
if (!*class)
- __objc_fatal("cannot find class for key %lu", key);
+ objc_error(nil, OBJC_ERR_BAD_CLASS,
+ "cannot find class for key %lu", key);
}
else
- __objc_fatal("expected class, got opcode %c", buf[0]);
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected class, got opcode %c", buf[0]);
}
return len;
}
else if ((buf[0]&_B_CODE) == _B_UCOMM)
{
if (key)
- __objc_fatal("cannot register use upcode...");
+ objc_error(nil, OBJC_ERR_BAD_KEY, "cannot register use upcode...");
len = __objc_read_nbyte_ulong(stream, (buf[0] & _B_VALUE), &key);
(*selector) = hash_value_for_key (stream->stream_table,
LONG2PTR(key));
}
else
- __objc_fatal("expected selector, got opcode %c", buf[0]);
+ objc_error(nil, OBJC_ERR_BAD_DATA,
+ "expected selector, got opcode %c", buf[0]);
}
return len;
}
}
default:
- fprintf(stderr, "objc_write_type: cannot parse typespec: %s\n", type);
- abort();
+ objc_error(nil, OBJC_ERR_BAD_TYPE,
+ "objc_write_type: cannot parse typespec: %s\n", type);
}
}
}
default:
- fprintf(stderr, "objc_read_type: cannot parse typespec: %s\n", type);
- abort();
+ objc_error(nil, OBJC_ERR_BAD_TYPE,
+ "objc_read_type: cannot parse typespec: %s\n", type);
}
}
res = objc_write_array (stream, t, len, va_arg(args, void*));
t = objc_skip_typespec (t);
if (*t != _C_ARY_E)
- __objc_fatal("expected `]', got: %s", t);
+ objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t);
}
break;
default:
- fprintf(stderr, "objc_write_types: cannot parse typespec: %s\n", type);
- abort();
+ objc_error(nil, OBJC_ERR_BAD_TYPE,
+ "objc_write_types: cannot parse typespec: %s\n", type);
}
}
va_end(args);
res = objc_read_array (stream, t, len, va_arg(args, void*));
t = objc_skip_typespec (t);
if (*t != _C_ARY_E)
- __objc_fatal("expected `]', got: %s", t);
+ objc_error(nil, OBJC_ERR_BAD_TYPE, "expected `]', got: %s", t);
}
break;
default:
- fprintf(stderr, "objc_read_types: cannot parse typespec: %s\n", type);
- abort();
+ objc_error(nil, OBJC_ERR_BAD_TYPE,
+ "objc_read_types: cannot parse typespec: %s\n", type);
}
}
va_end(args);
static int
__objc_no_write(FILE* file, char* data, int len)
{
- __objc_fatal ("TypedStream not open for writing");
+ objc_error (nil, OBJC_ERR_NO_WRITE, "TypedStream not open for writing");
}
static int
__objc_no_read(FILE* file, char* data, int len)
{
- __objc_fatal ("TypedStream not open for reading");
+ objc_error (nil, OBJC_ERR_NO_READ, "TypedStream not open for reading");
}
static int
;
sscanf (buffer, "GNU TypedStream %d", &stream->version);
if (stream->version != OBJC_TYPED_STREAM_VERSION)
- __objc_fatal ("cannot handle TypedStream version %d", stream->version);
+ objc_error (nil, OBJC_ERR_STREAM_VERSION,
+ "cannot handle TypedStream version %d", stream->version);
return 1;
}
static void __objc_finish_read_root_object(struct objc_typed_stream* stream)
{
node_ptr node;
- struct objc_list* free_list;
SEL awake_sel = sel_get_any_uid ("awake");
+ cache_ptr free_list = hash_new (64,
+ (hash_func_type) hash_ptr,
+ (compare_func_type) compare_ptrs);
/* resolve object forward references */
- free_list = list_cons(NULL, NULL);
for (node = hash_next (stream->object_refs, NULL); node;
node = hash_next (stream->object_refs, node))
{
while(reflist)
{
*((id*)reflist->head) = object;
- if (list_find(&free_list, reflist) == NULL)
- free_list = list_cons (reflist, free_list);
+ if (hash_value_for_key (free_list,reflist) == NULL)
+ hash_add (&free_list,reflist,reflist);
+
reflist = reflist->tail;
}
}
- list_mapcar (free_list, objc_free);
- list_free (free_list);
+
+ /* apply __objc_free to all objects stored in free_list */
+ for (node = hash_next (free_list, NULL); node;
+ node = hash_next (free_list, node))
+ objc_free ((void *) node->key);
+
+ hash_delete (free_list);
/* empty object reference table */
hash_delete (stream->object_refs);