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

			     browser_eng.c

   File: browser_eng.c
   Path: /home/fournigault/c/X11/xcoral-2.31/browser_eng.c
   Description: 
   Created: Fri Jan 27 10:44:37 MET 1995
   Author: Dominique Leveque
   Modified: Fri Jan 27 10:44:38 MET 1995
   Last maintained by: Dominique Leveque

   RCS $Revision$ $State$
   

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

   Note: 

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

   Copyright (c) : Dominique Leveque

   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 "proto_decl.h"

#include "result_types.h"
#include "file_dict.h"
#include "proc_dict.h"
#include "global_dict.h"
#include "class_dict.h"
#include "browser_eng.h"
#include "browser_pars.h"
#include "browser_util.h"



/*------------------------------------------------------------------------------
*/
StringTable* get_files_list () {
  FileRec*     current_file;
  StringTable* result;
  char**       current_entry;
  int          index;
  int          x_size;

  x_size = sizeof(char*) * (file_count + 1);
  result = (StringTable*) xmalloc(x_size);
  if (result != Null) {
    current_entry = (char**) result;
    for (index = 0; index < FILE_DICT_SIZE; index++) {
      current_file = file_dict[index];
      while(current_file != Null) {
        (*current_entry) = current_file->_name;
	    current_entry++;
	    current_file = current_file->_next;
      }
    }
    (*current_entry) = Null;
    qsort(result, file_count, sizeof(char*), sort_util);
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/

static int hiden_because_child(current_class)
    ClassRec* current_class;
{
  ParentRec* current_parent = current_class->_parents_list;
  
  while (current_parent) {
    ClassRec* parent = find_class(current_parent->_name);
    
    if (parent)
      if ((parent->_hide & HideChildrenOf) ||
	  hiden_because_child(parent))
	return 1;
    
    current_parent = current_parent->_next;
  }
  
  return 0;
}

StringTable* get_classes_list ()
{
  ClassRec*    current_class;
  StringTable* result;
  char**       current_entry;
  int          index;
  int          x_size;
  char*        infos;
  
  x_size = sizeof(char*) * (class_count + 1);
  result = (StringTable*) xmalloc(x_size);
  if (result != Null) {
    current_entry = (char**) result;
    for (index = 0; index < CLASS_DICT_SIZE; index++) {
      current_class = class_dict[index];
      while(current_class != Null) {
        (*current_entry) = current_class->_name;
	infos = (*current_entry) - CLASS_PLENGTH + 1;
	infos[0] = (current_class->_decl_file != Null) ? 'd' : '?';
	if (current_class->_decl & TEMPLATE_TYPE)
	  infos[1] = 'T';
	if (hiden_because_child(current_class)) {
	  current_class->_hide |= HidenChildren;
	  HIDE(current_class->_name);
	}
	else
	  current_class->_hide &= ~HidenChildren;
	if ((Hide_Bits & HideInternalTypes) &&
	    strchr(current_class->_name, ':')) {
	  current_class->_hide |= HideInternalTypes;
	  HIDE(current_class->_name);
	}
	else
	  current_class->_hide &= ~HideInternalTypes;
	if (current_class->_hide & UserHide)
	  HIDE(current_class->_name);
	else if (! (current_class->_hide & ~HideChildrenOf))
	  SHOW(current_class->_name);

	current_entry++;
	current_class = current_class->_next;
      }
    }
    (*current_entry) = Null;
    qsort(result, class_count, sizeof(char*), sort_util);
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
StringTable* get_parents_list (class_name, obj)
    char* class_name;
    int obj;
{
  StringTable* result;
  char**       current_entry;
  ClassRec*    current_class;
  ClassRec*    parent_class;
  ParentRec*   current_parent;
  int          x_size;
  char*        infos;

  result = Null; 
  current_class = find_class(class_name);
  if (current_class != Null) {
    x_size = sizeof(char*) * (current_class->_parents_count + 1);
    result = (StringTable*) xmalloc(x_size);
    if (result != Null) {
      current_entry  = (char**) result;
      current_parent = current_class->_parents_list;
      while (current_parent != Null) {
	if (obj)
	  (*current_entry) = (char *) current_parent;
	else
	  (*current_entry) = current_parent->_name;
	infos = current_parent->_name - CLASS_PLENGTH + 1;
	parent_class = find_class(*current_entry);
	if ((parent_class != Null) && (parent_class->_decl_file != Null))
	  *infos = 'd';
	else
	  *infos = '?';
	current_entry++;
	current_parent = current_parent->_next;
      }
      (*current_entry) = Null;
      if (!obj)
	qsort(result, current_class->_parents_count, sizeof(char*), sort_util);
    }
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
StringTable* get_sons_list(class_name)
    char* class_name;
{
  int          index;
  int          marked_count;
  ClassRec*    marked_list;
  ClassRec*    current_class;
  ParentRec*   current_parent;
  StringTable* result;
  char**       current_entry;
  int          x_size;
  char*        infos;

  marked_list  = Null;
  marked_count = 0;
  for (index = 0; index < CLASS_DICT_SIZE; index++) {
    current_class = class_dict[index];
    while (current_class != Null) {
      current_parent = current_class->_parents_list;
      while (current_parent != Null) {
        if (strcmp(current_parent->_name, class_name) == 0) {
          current_class->_next_marked = marked_list;
          marked_list                 = current_class;
          marked_count++;
        }
        current_parent = current_parent->_next;
      }
      current_class = current_class->_next;
    }
  }
  x_size = sizeof(char*) * (marked_count + 1);
  result = (StringTable*) xmalloc(x_size);
  if (result != Null) {
    current_entry = (char**) result;
    while (marked_list != Null) {
      (*current_entry) = marked_list->_name;
	  infos = (*current_entry) - CLASS_PLENGTH + 1;
	  if (marked_list->_decl_file != Null)
	    *infos = 'd';
	  else
	    *infos = '?';
	  current_entry++;
	  marked_list = marked_list->_next_marked;
    }
    (*current_entry) = Null;
    qsort(result, marked_count, sizeof(char*), sort_util);
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
MethodRec* marked_list;
int        marked_count;

#define END_MARKED_LIST ((MethodRec*) 0x00000001)


int sort_method(i,j)
  char** i;
  char** j;
{
  char* ti = *i;
  char* tj = *j;
  char* par_posit;
  int   result;

  if ((**i) == '~')
    ti = (*i) + 1;
  if ((**j) == '~')
    tj = (*j) + 1;
  par_posit = strchr(ti, '(');
  result    = strncmp(ti, tj, (par_posit - ti));
  if (result == 0) {
    if ((**i) == '~')
      result = 1;
    else if ((**j) == '~')
      result = -1;
    else {
      result = strcmp(*i, *j);
      if (result == 0) {
	return (*((*i) - METHOD_PLENGTH + 2) > *((*j) - METHOD_PLENGTH + 2))
          ? 1 : -1;
      }
    }
  }
  return(result);
}


void post_compute(result)
    StringTable* result;
{
  char**  current_entry;
  char*   current_depth;
  char*   infos;
  char*   virtual_method_name = "";
  int     virtual_flag;
  
  virtual_flag  = False;
  current_entry = (char**) result;
  while ((*current_entry) != Null) {
    infos = (*current_entry) - METHOD_PLENGTH + 1;
    if ((*infos) == 'V') {
      if (strcmp(virtual_method_name, (*current_entry)) == 0)
        (*infos) = 'v';
      else {
        virtual_flag        = True;
        virtual_method_name = (*current_entry);
      }
    }
    else if (virtual_flag == True) {
      if (strcmp(virtual_method_name, (*current_entry)) == 0)
        (*infos) = 'v';
      else
        virtual_flag = False;
    }
    current_depth = infos + 1;
    if ((*current_depth) == 0)
      (*current_depth) = 'L';
    else {
      (*current_depth) = '0' + (*current_depth);
      (*current_depth) = (((*current_depth) <= '9') ? (*current_depth) : '+');
      if (Hide_Bits & HideInherited)
	HIDE(*current_entry);
    }
    current_entry++;
  }
}


void get_inherit_list(current_class, max_scope, depth)
     ClassRec* current_class;
     ScopeType max_scope;
     int       depth;
{
  MethodRec*  current_method;
  ParentRec*  current_parent;

  current_method = current_class->_methods_list;
  while(current_method != Null) {
    if (   (current_method->_scope <= max_scope)
        && (current_method->_next_marked == Null)) {
      *(current_method->_name - METHOD_PLENGTH + 2) = depth;
	  current_method->_next_marked = marked_list;
	  marked_list                  = current_method;
	  marked_count++;
    }
    current_method = current_method->_next;
  }
  current_parent = current_class->_parents_list;
  if (depth < 255)
    depth++;
  while (current_parent != Null) {
    if (current_parent->_scope < PRIVATE_SCOPE) {
	    current_class = find_class(current_parent->_name);
	    if (current_class != Null)
	      get_inherit_list(current_class, PROTECTED_SCOPE, depth);
    }
    current_parent = current_parent->_next;
  }
}


StringTable* get_methods_list(class_name, cut)
    char* class_name;
    int cut;
{
  ClassRec*    current_class;
  MethodRec*   current_method;
  StringTable* result;
  char**       current_entry;
  int          x_size;
  char*        infos;

  result        = Null;
  marked_list   = END_MARKED_LIST;
  marked_count  = 0;
  current_class = find_class(class_name);
  if (current_class != Null) {
    get_inherit_list(current_class, PRIVATE_SCOPE, 0);
    if (marked_list != END_MARKED_LIST)  {
      x_size = sizeof(char*) * (marked_count + 1);
      result = (StringTable*) xmalloc(x_size);
      if (result != Null) {
        current_entry  = (char**) result;
        current_method = marked_list;
        while(current_method != END_MARKED_LIST) {
          (*current_entry) = current_method->_name;
          infos = (*current_entry) - METHOD_PLENGTH + 1;
          if (current_method->_decl_file != Null)
            *(infos + 2) = 'd';
          else
            *(infos + 2) = '?';
          if (current_method->_impl_file != Null)
            *(infos + 3) = (METHOD_IS_INLINE(current_method->_decl)) ? 'I' 
								     : 'i';
          else
            *(infos + 3) = '?';
	  if (METHOD_ISA_CONSTRUCTOR(current_method->_decl))
            *infos = 'c';
          else if ((*(current_method->_name)) == '~')
            *infos = 'd';
	  else if (METHOD_IS_VIRTUAL(current_method->_decl))
            *infos = 'V';
          else
            *infos = ' ';
	  if (Hide_Bits & HideProtected
	      && (current_method->_scope >= PROTECTED_SCOPE)) {
	    current_method->_hide |= HideProtected;
	    HIDE(current_method->_name);
	  }
	  else
	    current_method->_hide &= ~HideProtected;
	  if (Hide_Bits & HidePrivate
	      && (current_method->_scope == PRIVATE_SCOPE)) {
	    current_method->_hide |= HidePrivate;
	    HIDE(current_method->_name);
	  }
	  else {
	    current_method->_hide &= ~HidePrivate;
	    if (! current_method->_hide)
	      SHOW(current_method->_name);
	  }
	  current_entry++;
	  if (! cut)
	    current_method = current_method->_next_marked;
	  else {
	    marked_list = marked_list->_next_marked;
	    current_method->_next_marked = Null;
	    current_method = marked_list;
	  }
        }
        (*current_entry) = Null;
	if (cut)
	  qsort(result, marked_count, sizeof(char*), sort_method);
        post_compute(result);
      }
    }
  }
  return(result);
}



#undef END_MARKED_LIST

/*------------------------------------------------------------------------------
*/

AttributeRec* marked_attr_list;
int marked_attr_count;

#define END_MARKED_LIST ((AttributeRec*) 0x00000001)

void get_inherit_attr_list(current_class, max_scope, depth)
     ClassRec* current_class;
     ScopeType max_scope;
     int       depth;
{
  AttributeRec*  current_attr;
  ParentRec*  current_parent;
  
  current_attr = current_class->_attributes_list;
  while(current_attr != Null) {
    if (   (current_attr->_scope <= max_scope)
        && (current_attr->_next_marked == Null)) {
      *(current_attr->_name - ATTRIBUTE_PLENGTH + 1) = depth;
      current_attr->_next_marked = marked_attr_list;
      marked_attr_list                  = current_attr;
      marked_attr_count++;
    }
    current_attr = current_attr->_next;
  }
  current_parent = current_class->_parents_list;
  if (depth < 255)
    depth++;
  while (current_parent != Null) {
    if (current_parent->_scope < PRIVATE_SCOPE) {
      current_class = find_class(current_parent->_name);
      if (current_class != Null)
	get_inherit_attr_list(current_class, PROTECTED_SCOPE, depth);
    }
    current_parent = current_parent->_next;
  }
}

int sort_attribute(i,j)
  char** i;
  char** j;
{
  int result = strcmp(*i, *j);
  
  if (result)
    return result;
  
  if (*((*i) - ATTRIBUTE_PLENGTH + 2) == 'L')
    return -1;
  
  if (*((*j) - ATTRIBUTE_PLENGTH + 2) == 'L')
    return 1;
  
  return (*((*i) - ATTRIBUTE_PLENGTH + 2) > *((*j) - ATTRIBUTE_PLENGTH + 2))
          ? 1 : -1;
}

StringTable* get_attributes_list(class_name, cut)
    char* class_name;
    int cut;
{
  ClassRec*    current_class;
  AttributeRec*   current_attr;
  StringTable* result;
  char**       current_entry;
  int          x_size;
  char*        infos;

  result        = Null;
  marked_attr_list   = END_MARKED_LIST;
  marked_attr_count  = 0;
  current_class = find_class(class_name);
  if (current_class != Null) {
    get_inherit_attr_list(current_class, PRIVATE_SCOPE, 0);
    if (marked_attr_list != END_MARKED_LIST)  {
      x_size = sizeof(char*) * (marked_attr_count + 1);
      result = (StringTable*) xmalloc(x_size);
      if (result != Null) {
        current_entry  = (char**) result;
        current_attr = marked_attr_list;
        while(current_attr != END_MARKED_LIST) {
          (*current_entry) = current_attr->_name;
          infos = (*current_entry) - ATTRIBUTE_PLENGTH + 1;
	  if (Hide_Bits & HideProtected
	      && (current_attr->_scope >= PROTECTED_SCOPE)) {
	    current_attr->_hide |= HideProtected;
	    HIDE(current_attr->_name);
	  }
	  else
	    current_attr->_hide &= ~HideProtected;
	  if (Hide_Bits & HidePrivate
	      && (current_attr->_scope == PRIVATE_SCOPE)) {
	    current_attr->_hide |= HidePrivate;
	    HIDE(current_attr->_name);
	  }
	  else
	    current_attr->_hide &= ~HidePrivate;
	  if (*infos) {
	    if (Hide_Bits & HideInherited)
	      HIDE(*current_entry);
	    else if (! current_attr->_hide)
	      SHOW(*current_entry);
	    *infos += '0';
            *infos  = (((*infos) <= '9') ? (*infos) : '+');
	  }
	  else {
	    *infos = 'L';
	    if (! current_attr->_hide)
	      SHOW(*current_entry);
	  }
	  *(infos + 1) = (ATTRIBUT_IS_STATIC(current_attr->_decl)) ? 's' : ' ';
	  current_entry++;
	  if (! cut)
	    current_attr = current_attr->_next_marked;
	  else {
	    marked_attr_list = marked_attr_list->_next_marked;
	    current_attr->_next_marked = Null;
	    current_attr = marked_attr_list;
	  }
        }
        (*current_entry) = Null;
	if (cut)
	  qsort(result, marked_attr_count, sizeof(char*), sort_attribute);
      }
    }
  }
  return(result);
}

/*------------------------------------------------------------------------------
*/
Position* get_class_decl (class_name)
    char* class_name;
{
  Position*     result;
  ClassRec*     current_class;
  int           x_size;

  result = Null;
  current_class = find_class(class_name);
  x_size = sizeof(Position);
  if (   (current_class != Null)
      && (current_class->_decl_file != Null)
      && ((result = (Position*) xmalloc(x_size)) != Null)) {
    result->file_name   = current_class->_decl_file->_name;
    result->line_number = current_class->_decl_line;
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
char* get_method_class(method_name)
    char* method_name;
{
  MethodRec* current_method;
  int        x_size;

  x_size = sizeof(MethodRec);
  current_method = (MethodRec*) (method_name - x_size - METHOD_PLENGTH);
  return(current_method->_class_name);
}


/*------------------------------------------------------------------------------
*/
Position* get_method_decl (class_name, method_name)
    char* class_name;
    char* method_name;
{
  Position*     result;
  ClassRec*     current_class;
  MethodRec*    current_method;
  int           x_size;
  
  result = Null;
  current_class = find_class(class_name);
  if (current_class != Null) {
    current_method = current_class->_methods_list;
    while (current_method != Null) {
      if (strcmp(current_method->_name, method_name) == 0)
        break;
      current_method = current_method->_next;
    }
    x_size = sizeof(Position);
    if (   (current_method != Null)
        && (current_method->_decl_file != Null)
        && ((result = (Position*) xmalloc(x_size)) != Null)) {
      result->file_name   = current_method->_decl_file->_name;
      result->line_number = current_method->_decl_line;
    }
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
Position* get_method_impl (class_name, method_name)
     char* class_name;
     char* method_name;
{
  Position*     result;
  ClassRec*     current_class;
  MethodRec*    current_method;
  int           x_size;

  result = Null;
  current_class = find_class(class_name);
  if (current_class != Null) {
    current_method = current_class->_methods_list;
    while (current_method != Null) {
      if (strcmp(current_method->_name, method_name) == 0)
        break;
      current_method = current_method->_next;
    }
    x_size = sizeof(Position);
    if (   (current_method != Null)
        && (current_method->_impl_file != Null)
        && ((result = (Position*) xmalloc(x_size)) != Null)) {
      result->file_name   = current_method->_impl_file->_name;
      result->line_number = current_method->_impl_line;
    }
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
char* get_attribute_class(attr_name)
    char* attr_name;
{
  AttributeRec* current_attr;
  int        x_size;

  x_size = sizeof(AttributeRec);
  current_attr = (AttributeRec*) (attr_name - x_size - ATTRIBUTE_PLENGTH);
  return(current_attr->_class_name);
}


/*------------------------------------------------------------------------------
*/
Position* get_attribute_decl (class_name, attr_name)
    char* class_name;
    char* attr_name;
{
  Position*     result;
  ClassRec*     current_class;
  AttributeRec*    current_attr;
  int           x_size;
  
  result = Null;
  current_class = find_class(class_name);
  if (current_class != Null) {
    current_attr = current_class->_attributes_list;
    while (current_attr != Null) {
      if (strcmp(current_attr->_name, attr_name) == 0)
        break;
      current_attr = current_attr->_next;
    }
    x_size = sizeof(Position);
    if (   (current_attr != Null)
        && (current_attr->_decl_file != Null)
        && ((result = (Position*) xmalloc(x_size)) != Null)) {
      result->file_name   = current_attr->_decl_file->_name;
      result->line_number = current_attr->_decl_line;
    }
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
StringTable* get_procs_list (prefix)
    char * prefix;
{
  ProcRec*     current_proc;
  StringTable* result;
  char**       current_entry;
  int          index;
  int          x_size;
  char*        infos;
  unsigned pfxlen;
  x_size = sizeof(char*) * (proc_count + 1);
  result = (StringTable*) xmalloc(x_size);
  if (result != Null) {
    if (prefix)
      pfxlen = strlen(prefix);
    current_entry = (char**) result;
    for (index = 0; index < PROC_DICT_SIZE; index++) {
      current_proc = proc_dict[index];
      while(current_proc != Null) {
	if (prefix) {
	  if (strncmp(current_proc->_name, prefix, pfxlen)) {
	    current_proc = current_proc->_next;
	    continue;
	  }
	  (*current_entry) = (char *) current_proc;
	}
	else
	  (*current_entry) = current_proc->_name;
	infos = current_proc->_name - PROC_PLENGTH + 1;
	if (current_proc->_decl & STATIC_PROC)
	  infos[0] = 's';
	if (current_proc->_decl & INLINE_PROC)
	  infos[1] = 'I';
	if (current_proc->_decl & TEMPLATE_PROC)
	  infos[2] = 'T';
	if ((current_proc->_decl & STATIC_PROC) &&
	    (Hide_Bits & HideStaticFunctions)) {
	  current_proc->_hide |= HideStaticFunctions;
	  HIDE(current_proc->_name);
	}
	else
	  current_proc->_hide &= ~HideStaticFunctions;
	if (current_proc->_hide & UserHide)
	  HIDE(current_proc->_name);
	else if (! current_proc->_hide)
	  SHOW(current_proc->_name);

	current_entry++;
	current_proc = current_proc->_next;
      }
    }
    (*current_entry) = Null;
    if (prefix) {
      if (! *result) {
	free(result);
	return 0;
      }
    }
    else
      qsort(result, proc_count, sizeof(char*), sort_util);
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
Position* get_proc_impl (proc_name)
    char* proc_name;
{
  Position*     result;
  ProcRec*      current_proc;
  int           x_size;
 
  result = Null;
  current_proc = find_proc(proc_name);
  x_size = sizeof(Position);
  if (   (current_proc != Null)
      && (current_proc->_impl_file != Null)
      && ((result = (Position*) xmalloc(x_size)) != Null)) {
    result->file_name   = current_proc->_impl_file->_name;
    result->line_number = current_proc->_impl_line;
  }
  return(result);
}



/*------------------------------------------------------------------------------
*/
StringTable* get_globals_list(prefix)
    char * prefix;
{
  GlobalRec*   current_global;
  StringTable* result;
  char**       current_entry;
  int          index;
  int          x_size;
  char*        infos;
  unsigned pfxlen;

  x_size = sizeof(char*) * (global_count + 1);
  result = (StringTable*) xmalloc(x_size);
  if (result != Null) {
    if (prefix)
      pfxlen = strlen(prefix);
    current_entry = (char**) result;
    for (index = 0; index < GLOBAL_DICT_SIZE; index++) {
      current_global = global_dict[index];
      while(current_global != Null) {
	if (prefix) {
	  if (strncmp(current_global->_name, prefix, pfxlen)) {
	    current_global = current_global->_next;
	    continue;
	  }
	  (*current_entry) = (char *) current_global;
	}
	else
	  (*current_entry) = current_global->_name;
	infos = (*current_entry) - GLOBAL_PLENGTH + 1;
	if (current_global->_static) {
	  *(infos) = 's';
	  if (Hide_Bits & HideStaticGlobals)
	    current_global->_hide |= HideStaticGlobals;
	  else
	    current_global->_hide &= ~HideStaticGlobals;
	  HIDE(current_global->_name);
	}
	else {
	  current_global->_hide &= ~HideStaticGlobals;
	  *(infos) = ' ';
	}
	if (current_global->_hide & UserHide)
	  HIDE(current_global->_name);
	else if (! current_global->_hide)
	  SHOW(current_global->_name);
	current_entry++;
	current_global = current_global->_next;
      }
    }
    (*current_entry) = Null;
    if (prefix) {
      if (! *result) {
	free(result);
	return 0;
      }
    }
    else
      qsort(result, global_count, sizeof(char*), sort_util);
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
Position* get_global_impl (global_name)
    char* global_name;
{
  Position*     result;
  GlobalRec*    current_global;
  int           x_size;
 
  result = Null;
  current_global = find_global(global_name);
  x_size = sizeof(Position);
  if (   (current_global != Null)
      && (current_global->_impl_file != Null)
      && ((result = (Position*) xmalloc(x_size)) != Null)) {
    result->file_name   = current_global->_impl_file->_name;
    result->line_number = current_global->_impl_line;
  }
  return(result);
}


/*------------------------------------------------------------------------------
*/
void parse_file(file_name)
     char* file_name;
{
  parsed_file = find_file(file_name);
  if (parsed_file != Null) {
    proc_eraze_file(file_name);
    global_eraze_file(file_name);
    class_eraze_file(file_name);
  }
  else
    parsed_file = create_file(file_name);
  if (parsed_file != Null) {
    browser_yyparse(file_name);
    garbage_global();
    garbage_proc();
    garbage_class();
  }
  parsed_file = Null;
  class_cache = Null;
}


/*------------------------------------------------------------------------------
*/
void delete_file(file_name)
     char* file_name;
{
  FileRec* current_file;

  current_file = find_file(file_name);
  if (current_file != Null) {
    proc_eraze_file(file_name);
    class_eraze_file(file_name);
    global_eraze_file(file_name);
    garbage_proc();
    garbage_class();
    garbage_global();
  }
  remove_file(file_name);
}


/*------------------------------------------------------------------------------
*/

void browser_show_all()
{
  int index;
  
  Hide_Bits = 0;
  {
    for (index = 0; index < CLASS_DICT_SIZE; index++) {
      ClassRec* current_class = class_dict[index];
      
      while (current_class) {
	MethodRec* current_method = current_class->_methods_list;
	AttributeRec* current_attr = current_class->_attributes_list;
	
	SHOW(current_class->_name);
	current_class->_hide = 0;
	
	while(current_method != Null) {
	  SHOW(current_method->_name);
	  current_method->_hide = 0;
	  current_method = current_method->_next;
	}
	while (current_attr) {
	  SHOW(current_attr->_name);
	  current_attr->_hide = 0;
	  current_attr = current_attr->_next;
	}
	current_class = current_class->_next;
      }
    }
  }
  {
    ProcRec* current_proc;
    
    for (index = 0; index < PROC_DICT_SIZE; index++) {
      current_proc = proc_dict[index];
      
      while (current_proc) {
	SHOW(current_proc->_name);
	current_proc->_hide = 0;
	current_proc = current_proc->_next;
      }
    }
  }
  {
    GlobalRec* current_global;
    
    for (index = 0; index < GLOBAL_DICT_SIZE; index++) {
      current_global = global_dict[index];
      
      while (current_global) {
	SHOW(current_global->_name);
	current_global->_hide = 0;
	current_global = current_global->_next;
      }
    }
  }
}


/*------------------------------------------------------------------------------
*/
void BrowserHide(selected_class_name)
    char * selected_class_name;
{
  FCT (void, ClearListBox, () );
  FCT (void, FillList, (char *str) );
  FCT (char *, SelectFromListBox, (char *msg) );

  static char *msgs[] = {
    "show all",
    "show protected and private members",
    "hide protected and private members",
    "hide private members",
    "show inherited members",
    "hide inherited members",
    "show static functions",
    "hide static functions",
    "show static globals",
    "hide static globals",
    "show internal types",
    "hide internal types",
    "show children of selected class",
    "hide children of selected class"
  };
  char * str;
  ClassRec* parent =
    (selected_class_name) ? find_class(selected_class_name + CLASS_PLENGTH) : 0;
    
  ClearListBox();
  FillList(msgs[0]);
  if (Hide_Bits & HideProtected)
    FillList(msgs[1]);
  else {
    FillList(msgs[2]);
    if (Hide_Bits & HidePrivate)
      FillList(msgs[1]);
    else
      FillList(msgs[3]);
  }
  FillList((Hide_Bits & HideInherited) ? msgs[4] : msgs[5]);
  FillList((Hide_Bits & HideInternalTypes) ? msgs[10] : msgs[11]);
  FillList((Hide_Bits & HideStaticFunctions) ? msgs[6] : msgs[7]);
  FillList((Hide_Bits & HideStaticGlobals) ? msgs[8] : msgs[9]);
  if (parent)
    FillList((parent->_hide & HideChildrenOf) ? msgs[12] : msgs[13]);
  
  if (! (str = SelectFromListBox("Browser objects visibility")))
    return;
  if (! strcmp(str, msgs[0]))
    browser_show_all();
  else if (! strcmp(str, msgs[1]))
    Hide_Bits &= ~(HidePrivate | HideProtected); 
  else if (! strcmp(str, msgs[2]))
    Hide_Bits |= HidePrivate | HideProtected;
  else if (! strcmp(str, msgs[3]))
    Hide_Bits |= HidePrivate;
  else if (! strcmp(str, msgs[4]))
    Hide_Bits &= ~HideInherited;
  else if (! strcmp(str, msgs[5]))
    Hide_Bits |= HideInherited;
  else if (! strcmp(str, msgs[6]))
    Hide_Bits &= ~HideStaticFunctions;
  else if (! strcmp(str, msgs[7]))
    Hide_Bits |= HideStaticFunctions;
  else if (! strcmp(str, msgs[8]))
    Hide_Bits &= ~HideStaticGlobals;
  else if (! strcmp(str, msgs[9]))
    Hide_Bits |= HideStaticGlobals;
  else if (! strcmp(str, msgs[10]))
    Hide_Bits &= ~HideInternalTypes;
  else if (! strcmp(str, msgs[11]))
    Hide_Bits |= HideInternalTypes;
  else if (! strcmp(str, msgs[12]))
    parent->_hide &= ~HideChildrenOf;
  else if (! strcmp(str, msgs[13]))
    parent->_hide = HideChildrenOf;
  
  RefreshBrowserInfos();
}

/*------------------------------------------------------------------------------
*/
	  
void init_browser() {
  init_file();
  init_proc();
  init_class();
}
