/* ########################################################################

			      global_dict.c

   File: global_dict.c
   Path: /home/fournigault/c/X11/xcoral-2.31/global_dict.c
   Description: 
   Created: Fri Jan 27 11:25:07 MET 1995
   Author: Bruno Pages
   Modified: Fri Jan 27 11:25:08 MET 1995
   Last maintained by: Bruno Pages

   RCS $Revision$ $State$
   

   ########################################################################

   Note: 

   ########################################################################

   Copyright (c) : Bruno Pages

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   ######################################################################## */


#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#include <stdio.h>

#include "result_types.h"
#include "file_dict.h"
#include "global_dict.h"
#include "browser_util.h"

/*------------------------------------------------------------------------------
//                         Le dictionnaire des globals
//------------------------------------------------------------------------------
*/

GlobalRec* global_dict[GLOBAL_DICT_SIZE];

int global_count = 0;


/*------------------------------------------------------------------------------
*/
GlobalRec* create_global(global_name, staticp, parsed_file)
    char* global_name;
    int staticp;
    char * parsed_file;
{
  GlobalRec**  head;
  GlobalRec*   current_global;
  int        x_size;
  
  get_head_Rec(global_name, global_dict, GLOBAL_DICT_SIZE, head);
  iter_Rec(global_name, GlobalRec, head, current_global) {
    if (current_global->_impl_file &&
	((! strcmp(parsed_file, current_global->_impl_file->_name)) ||
	 ((! staticp) && (! current_global->_static))))
      return current_global;
  }
  x_size = sizeof(GlobalRec) + GLOBAL_PLENGTH + strlen(global_name)  + 1;
  current_global = (GlobalRec*) xmalloc(x_size);
  if (current_global != Null) {
    create_Rec(global_name, GlobalRec, head, current_global, GLOBAL_PREFIX, GLOBAL_PLENGTH);
    current_global->_impl_file = Null;
    current_global->_impl_line = 0;
    current_global->_static = 0;
    current_global->_hide = 0;
    global_count++;
  }

  return(current_global);
}


/*------------------------------------------------------------------------------
*/
GlobalRec* find_global(global_name)
  char* global_name;
{
  GlobalRec**  head;
  GlobalRec*   current_global;

  get_head_Rec(global_name, global_dict, GLOBAL_DICT_SIZE, head);
  assoc_Rec(global_name, GlobalRec, head, current_global);
  return(current_global);
}


/*------------------------------------------------------------------------------
*/
typedef long Bits;

#define LAST_BIT  ((sizeof(Bits) * 8) - 1)

static Bits erazed_bits[(GLOBAL_DICT_SIZE + LAST_BIT) / (LAST_BIT + 1)];


void global_eraze_file(file_name)
    char* file_name;
{
  Bits*      erazed_slice;
  FileRec*   current_file;
  GlobalRec*   current_global;
  int        index;
  
  current_file = find_file(file_name);
  if (current_file != Null) {
    erazed_slice = erazed_bits;
    for (index = 0; index < GLOBAL_DICT_SIZE; index++) {
      current_global = global_dict[index];
      while (current_global != Null) {
        if (current_global->_impl_file == current_file) {
          current_global->_impl_file = Null;
          current_global->_impl_line = 0;
          (*erazed_slice) |= ((0x00000001L) << (index & LAST_BIT));
        }
	    current_global = current_global->_next;
      }
      if ((index & LAST_BIT) == LAST_BIT)
        erazed_slice++;
    }
  }  
}


/*------------------------------------------------------------------------------
*/
void garbage_global()
{
  Bits*     erazed_slice;
  GlobalRec*  previous_global;
  GlobalRec*  current_global;
  GlobalRec*  next_global;
  int       index;

  erazed_slice = erazed_bits;
  for (index = 0; index < GLOBAL_DICT_SIZE; index++) {
    if ((*erazed_slice) == 0) {
      index += LAST_BIT;
      erazed_slice++;
    }
    else {
      if (((*erazed_slice) & ((0x00000001L) << (index & LAST_BIT))) != 0) {
        previous_global = Null;
        current_global = global_dict[index];
        while (current_global != Null) {
          if (current_global->_impl_file == Null) {
            next_global = current_global->_next;
            if (previous_global == Null)
              global_dict[index] = next_global;
            else
              previous_global->_next = next_global;
            --global_count;
            free(current_global);
            current_global = next_global;
          }
          else {
            previous_global = current_global;
	    current_global  = current_global->_next;
	      }
        }
      }
      if ((index & LAST_BIT) == LAST_BIT) {
        *erazed_slice = 0;
        erazed_slice++;
      }
    }
  }
}  


/*------------------------------------------------------------------------------
*/
void init_global() {
  Bits* erazed_slice;
  int   index;

  erazed_slice = erazed_bits;
  for (index = 0; index < GLOBAL_DICT_SIZE; index++) {
    if ((index & LAST_BIT) == LAST_BIT) {
      *erazed_slice = 0;
      erazed_slice++;
    }
    global_dict[index] = Null;
  }
}




