/*
 *	ListInts.c
 *
 *	This program produces a list of interrupt handlers on it's standard
 *	output.
 *
 *	Program		Date		Action
 *	D. Thomas	25 April 1987	v1.0 Initial Coding.
 *
 */

#include "exec/execbase.h"
#include "exec/memory.h"
#include "functions.h"

extern struct ExecBase *SysBase;	/* Exec's base ptr */

main ()

{

  register struct Interrupt *t;   	/* ptr to int list */
  register struct List       head;	/* for my copy of the int list */

  NewList (&head);

  Disable ();

  if (getlist (&SysBase->IntrList, &head))
    cleanup (&head);

  Enable ();

  puts ("Prty Code Vec Data Vec Name");

  while (t = (struct Interrupt *) RemHead (&head)) {

    printf ("%4d %8lx %8lx %s\n",
      t->is_Code, t->is_Data,
      (t->is_Node.ln_Name ? t->is_Node.ln_Name : "<unset>"));
    
    if (t->is_Node.ln_Name)
      FreeMem (t->is_Node.ln_Name, (long) strlen (t->is_Node.ln_Name) + 1);
    FreeMem (t, (long) sizeof *t);

  }

  exit (0);

}

freelist (l)

struct List *l;

{

  struct Interrupt *t;

  while (t = (struct Interrupt *) RemHead (l)) {
    if (t->is_Node.ln_Name)
      FreeMem (t->is_Node.ln_Name, (long) strlen (t->is_Node.ln_Name) + 1);
    FreeMem (t, (long) sizeof *t);
  }

}

cleanup (l)

struct List *l;

{

  Enable ();
  freelist (l);
  puts ("Out of Memory!");
  exit (0);

}

getlist (tl, l)

struct List *tl;
struct List *l;

{

  register struct Interrupt *t;

  for (t = (struct Interrupt *) tl->lh_Head;
       t->is_Node.ln_Succ;
       t = (struct Interrupt *) t->is_Node.ln_Succ)
    if (onenode (t, l))
      return TRUE;

  return FALSE;

}

onenode (t, l)

struct Interrupt *t;
struct List      *l;

{

  register struct Interrupt *tc;

  if (!(tc = (struct Interrupt *) AllocMem ((long) sizeof *t, MEMF_CLEAR)))
      return TRUE;
  *tc = *t;

  if (t->is_Node.ln_Name) {
    if (!(tc->is_Node.ln_Name = (char *) AllocMem ((long) strlen (t->is_Node.ln_Name) + 1, 0L))) {
      FreeMem (tc, (long) sizeof *tc);
      return TRUE;
    }
    strcpy (tc->is_Node.ln_Name, t->is_Node.ln_Name);
  }

  AddTail (l, tc);

  return FALSE;

}
