ftp.nice.ch/pub/next/developer/languages/c/djgpp-NS.s.tar.gz#/djgpp/src/gcc-260/cp/lib-exce.c

This is lib-exce.c in view mode; [Download] [Up]

/* terminate(), unexpected(), set_terminate(), set_unexpected()
   as well as the default terminate func  and default unexpected func
   ====================================================================== */ 

typedef void (*vfp)();

void
__default_terminate()
{
 abort();
}

void
__default_unexpected()
{
 __default_terminate();
}

static vfp __terminate_func = __default_terminate;
static vfp __unexpected_func = __default_unexpected;

vfp
set_terminate(func)
vfp func;
{
 vfp old = __terminate_func;

 __terminate_func = func;

 return old;
}

vfp
set_unexpected(func)
vfp func;
{
 vfp old = __unexpected_func;

 __unexpected_func = func;

 return old;
}

void
terminate()
{
 __terminate_func();
}

void
unexpected()
{
 __unexpected_func();
}
/* ====================================================================== */ 

typedef struct {
    void *start;
    void *end;
    void *exception_handler;
 } exception_table;

static int except_table_pos = 0;
static void *except_pc = (void *)0;
extern exception_table __EXCEPTION_TABLE__[];

/* this routine takes a pc, and the address of the exception handler associated
   with the closest exception table handler entry associated with that PC,
   or 0 if there are no table entries the PC fits in.  The algorithm works
   something like this:

    while(current_entry exists) {
        if(current_entry.start < pc )
            current_entry = next_entry;
        else {
            if(prev_entry.start <= pc && prev_entry.end > pc) {
                save pointer to prev_entry;
                return prev_entry.exception_handler;
             }
            else return 0;
         }
     }
    return 0;

   Assuming a correctly sorted table (ascending order) this routine should
   return the tighest match...

   In the advent of a tie, we have to give the last entry, as it represents
   an inner block.
 */


void *
__find_first_exception_table_match(pc)
void *pc;
{
  extern int printf(...);
  exception_table *table = __EXCEPTION_TABLE__;
  int pos = 0;
  int best = 0;
#if 0
  printf("find_first_exception_table_match(): pc = %x!\n",pc);
#endif

  except_pc = pc;

#if 0
  /* We can't do this yet, as we don't know that the table is sorted.  */
  do {
    ++pos;
    if (table[pos].start > except_pc)
      /* found the first table[pos].start > except_pc, so the previous
	 entry better be the one we want! */
      break;
  } while(table[pos].exception_handler != (void*)-1);

  --pos;
  if (table[pos].start <= except_pc && table[pos].end > except_pc)
    {
      except_table_pos = pos;
#if 0
      printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler);
#endif
      return table[pos].exception_handler;
    }
#else
  while (table[++pos].exception_handler != (void*)-1) {
    if (table[pos].start <= except_pc && table[pos].end > except_pc)
      {
	/* This can apply.  Make sure it is better or as good as the previous
	   best.  */
	/* The best one ends first. */
	if (best == 0 || (table[pos].end <= table[best].end
			  /* The best one starts last.  */
			  && table[pos].start >= table[best].start))
	  best = pos;
      }
  }
  if (best != 0)
    return table[best].exception_handler;
#endif

#if 0
  printf("find_first_eh_table_match(): else: returning NULL!\n");
#endif
  return (void*)0;
}


#if 0
/* this routine returns the next tighest exception table match for the
   current except_pc, or 0 if there aren't any wider entries (meaning
   we need to either unwind a level and call
   find_first_exception_table_match() with the new pc, or we need to
   call terminate() because there are no more layers to unwind. */

void *
__find_next_exception_table_match()
{
 exception_table *table = __EXCEPTION_TABLE__;
 int pos = except_table_pos;
 extern int printf(...);

 printf("__find_next_exception_table_match(): table = %x, pos = %d, except_pc = %x\n",table,pos,except_pc);

 if(! --pos) {
	 except_table_pos = 1;
     return (void*)0;
  }

 if(table[pos].start <= except_pc && table[pos].end >= except_pc) {
     except_table_pos = pos;
 printf("__find_next_exception_table_match(): found match: %x\n",table[pos].exception_handler);
     return table[pos].exception_handler;
  }
 else {
	 except_table_pos = 1;
     return (void*)0;
  }
}
#endif

#if 0
void
__unwind_function(void *frameaddr)
{
 extern int printf(...);

 printf("__unwind_function(): frameaddr = %x\n",frameaddr);
}
#endif

int
__throw_type_match (const char *catch_type, const char *throw_type)
{
 extern int printf(...);

#if 0
 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n",
	catch_type, throw_type);
#endif
 return strcmp (catch_type, throw_type);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.