#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <yafl_usr.h>
#include <yafl_rnt.h>
#include "dbx_rnt.h"
#include "dbx_modu.h"
#include "dbx_type.h"
#include "dbx_clas.h"
#include "dbx_meth.h"
#include "dbx_matc.h"
#include "dbx_worl.h"

static dbx_module module_table[MAX_MODULES];
static unsigned used_modules = 0;

dbx_module *new_module YPARAMS0
{
  dbx_module *p;
  assert(used_modules < MAX_MODULES);
  p = &module_table[used_modules];
  used_modules++;
  memset (p,0,sizeof(dbx_module));
  return p;
}

void dump_modules YPARAMS0 
{
  int i;
  dbx_module *p;
  char a[200];
  
  emit_stdout("dbx_module\tfile\n\n");
  for (i = 0;i < used_modules;i++)
  {
    p = &module_table[i];
    sprintf(a, "%s\t%s\n",p->name,p->source_file_name);
    emit_stdout(a);
  }
  emit_nl();
}

int module_count YPARAMS0
{
  return used_modules;
}

/* searches in the array of line numbers associated with a module */
/* to know if the line contains a YAFL statement so that a breakpoint */
/* can be placed on it */

int is_statement YPARAMS4(dbx_module *,     pm,
                         unsigned,         line)
{
  unsigned *p;
  assertp(pm); 
  p  = pm->line_numbers;
  if (p)
  {
    while ((*p != line)&&(*p != 0))
      p++;
    return(*p == line);
  }
}

/* search a class containing the line in the module */
dbx_class *line_in_class YPARAMS4(dbx_module *,  pmo,
                                 unsigned,      line)
{
  dbx_class *pc;
  dbx_class *pcl;
  assertp(pmo);
  assert(line > 0);
  pc = first_class(pmo);
  pcl = NULL;
  while (pc)
  {
    if ((class_beginline(pc) <= line)&&(line <= class_endline(pc)))
    {
      pcl = pc;
      pc = NULL;
    }
    else
    {
      pc = next_class(pc);    
    }
  }
  return pcl;
}                                 

/* search the inner method containing the line in the module */
/* the inner method has the highest begin line number (and the */
/* lowest end line number) of all the methods containing the line */

dbx_method *line_in_method YPARAMS4(dbx_module *,  pmo,
                                   unsigned,      line)
{
  dbx_class *pc;
  dbx_method *pme;
  dbx_method *pmet = NULL;
  int max = 0;
  assertp(pmo);
  assert(line > 0);
  pc = first_class(pmo);
  while (pc)
  {
    pme = first_method(pc);
    while (pme)
    {
      if ((method_beginline(pme) <= line) && (line <= method_endline(pme)))
      {
        if (method_beginline(pme) > max)
      	{
      	  max = method_beginline(pme);
      	  pmet = pme;
      	}
      }
      pme = next_method(pme);
    }
    pc = next_class(pc);
  }
  return pmet;
}

dbx_module *find_next_module YPARAMS4(dbx_module *,  pm,
                                     char *,       pattern)
{
  dbx_module *pmod = NULL;
  while (pm)
  {
    if (dbx_match(module_name(pm),pattern))
    {
      pmod = pm;
      pm = NULL;
    }
    else
    {
      pm = next_module(pm);
    }
  }
  return pmod;
}

dbx_module *find_prev_module YPARAMS4(dbx_module *,  pm,
                                     char *,       pattern)
{
  dbx_module *pmod = NULL;
  while (pm)
  {
    if (dbx_match(module_name(pm),pattern))
    {
      pmod = pm;
      pm = NULL;
    }
    else
    {
      pm = prev_module(pm);
    }
  }
  return pmod;
}

static void do_init YPARAMS0
{
}

void init_dbx_modu YPARAMS0
{
  static int initialized;
  if (!initialized)
  {
    init_dbx_worl();
    do_init();
    initialized = 1;
  }
}

void term_dbx_modu YPARAMS0
{
}
