//Copyright, 2001-2003, Astra Network Inc.  All Rights Reserved

//This source code has been published by Astra Network Inc. However, any
//use, reproduction, modification, distribution or transfer of this
//software, or any software which includes or is based upon any of this
//code, is only permitted if expressly authorized by a written license
//agreement from Astra. Contact your Astra representative directly for
//more information.

#include <stdio.h>
#include <string.h>

#include "module_load.h"
#include "global_bits.h"

extern const olmod_module_t object_global_overlord_table[];

size_t modtable_size = 0;
size_t modtable_alloc = 0;

modlist_entry_t *
extend_modtable (void)
     /*@globals modtable, modtable_alloc, modtable_size;@ */ ;
     void insert_module (olmod_module_t * newmod)
     /*@globals modtable, modtable_size;@ */ ;

     void load_modules (char /*@unused@ */ **ignored)
{
  int i = 0;
  const olmod_module_t *ogot = object_global_overlord_table;

  if (verbose != 0)
    printf ("Reading built-in modules.\n");

  while (ogot[i].keyword != NULL)
    {
      insert_module (&ogot[i]);
      i++;
    }
  if (verbose != 0)
    printf ("Loaded %d modules.\n", i);
  checkmodules ();
}

void
insert_module (olmod_module_t * newmod)
     /*@globals modtable, modtable_size;@ */
{
  modlist_entry_t *modentry = NULL;
  int i;

  if (newmod->keyword == NULL)
    {
      fatal ("Internal error: passed NULL keyword");
    }

  for (i = 0; i < (int) modtable_size; i++)
    {
      if (modtable[i].module->keyword == NULL || newmod->keyword == NULL)
	{
	  fatal ("Internal error: NULL modtable keyword");
	}
      if (strcmp (modtable[i].module->keyword, newmod->keyword) == 0)
	{
	  modentry = &modtable[i];
	  break;
	}
    }

  if (verbose != 0)
    printf ("Adding built-in module \"%s\"", newmod->keyword);

  if (modentry == NULL)
    {
      modentry = extend_modtable ();
      if (verbose != 0)
	printf ("\n");
    }
  else
    {
      if (verbose != 0)
	printf (" (replacing already loaded module)\n");
    }
  modentry->dlhandle = NULL;
  modentry->module = newmod;
}

modlist_entry_t *
extend_modtable (void)		/*@globals modtable, modtable_alloc, modtable_size;@ */
{
  if (modtable == NULL)
    {
      modtable = malloc (32 * sizeof (modlist_entry_t));
      modtable_alloc = 32;
    }
  if ((modtable_size + 1) > modtable_alloc)
    {
      modtable =
	realloc (modtable, modtable_alloc * 2 * sizeof (modlist_entry_t));
      modtable_alloc *= 2;
    }
  if (modtable == NULL)
    {
      fatal ("Out of Memory while loading modules!");
    }
  return &modtable[modtable_size++];
}
