diff --git a/gcc/objc/archive.c b/gcc/objc/archive.c index c832b466bea..2edb056acba 100644 --- a/gcc/objc/archive.c +++ b/gcc/objc/archive.c @@ -1,5 +1,5 @@ /* 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. @@ -37,11 +37,6 @@ extern int fflush(FILE*); #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 @@ -362,7 +357,8 @@ __objc_write_extension (struct objc_typed_stream* stream, unsigned char code) 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 @@ -397,7 +393,8 @@ objc_write_root_object (struct objc_typed_stream* stream, id object) { 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; @@ -524,8 +521,9 @@ objc_read_char (struct objc_typed_stream* stream, char* val) } 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; } @@ -545,8 +543,9 @@ objc_read_unsigned_char (struct objc_typed_stream* stream, unsigned char* val) 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; } @@ -566,7 +565,8 @@ objc_read_short (struct objc_typed_stream* stream, short* value) 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) @@ -594,7 +594,8 @@ objc_read_unsigned_short (struct objc_typed_stream* stream, 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) @@ -620,7 +621,7 @@ objc_read_int (struct objc_typed_stream* stream, int* value) 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) @@ -647,7 +648,7 @@ objc_read_long (struct objc_typed_stream* stream, long* value) 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) @@ -667,7 +668,7 @@ __objc_read_nbyte_uint (struct objc_typed_stream* stream, 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; @@ -703,7 +704,7 @@ __objc_read_nbyte_ulong (struct objc_typed_stream* stream, 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; @@ -784,7 +785,8 @@ objc_read_string (struct objc_typed_stream* stream, 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)); } } @@ -829,13 +831,14 @@ objc_read_object (struct objc_typed_stream* stream, id* object) /* 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)); } @@ -853,13 +856,15 @@ objc_read_object (struct objc_typed_stream* stream, id* object) 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; } @@ -900,15 +905,17 @@ objc_read_class (struct objc_typed_stream* stream, Class* class) 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; } @@ -952,14 +959,15 @@ objc_read_selector (struct objc_typed_stream* stream, SEL* selector) 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; } @@ -1057,8 +1065,8 @@ objc_write_type(TypedStream* stream, const char* type, const void* data) } 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); } } @@ -1150,8 +1158,8 @@ objc_read_type(TypedStream* stream, const char* type, void* data) } 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); } } @@ -1246,13 +1254,13 @@ objc_write_types (TypedStream* stream, const char* 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); @@ -1338,13 +1346,13 @@ objc_read_types(TypedStream* stream, const char* type, ...) 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); @@ -1414,13 +1422,13 @@ __objc_feof(FILE* file) 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 @@ -1434,7 +1442,8 @@ __objc_read_typed_stream_signature (TypedStream* stream) ; 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; } @@ -1459,11 +1468,12 @@ static void __objc_finish_write_root_object(struct objc_typed_stream* stream) 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)) { @@ -1473,13 +1483,19 @@ static void __objc_finish_read_root_object(struct objc_typed_stream* stream) 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);