changeset 39514:542ef74db0d2

(struct alias): Add two new struct members: NAMESP and ALIASEE to help work with namespace aliases. (struct sym): Remove struct member NAMESP_ALIASES. (namespace_alias_table): New variable. (make_namespace): Add parameter CONTEXT. (check_namespace): New function. (find_namespace): Add parameter CONTEXT. (check_namespace_alias): New function. (register_namespace_alias): Change type of parameter OLD_NAME. Search for already defined alias in NAMESPACE_ALIAS_TABLE. (check_namespace): New function. (enter_namespace): Call find_namespace with CONTEXT parameter. (match_qualified_namespace_alias): New function. (parse_qualified_ident_or_type): Fixed typo in comment. While parsing qualified ident or type update namespace context and restore it on exit. (parse_qualified_param_ident_or_type): Fixed typo in comment. (globals): Changed handling of namespace aliases. (version): Added year 2001.
author Gerd Moellmann <gerd@gnu.org>
date Mon, 01 Oct 2001 07:25:14 +0000
parents 4da5c4328f00
children da28750c22cd
files lib-src/ebrowse.c
diffstat 1 files changed, 143 insertions(+), 40 deletions(-) [+]
line wrap: on
line diff
--- a/lib-src/ebrowse.c	Mon Oct 01 07:03:13 2001 +0000
+++ b/lib-src/ebrowse.c	Mon Oct 01 07:25:14 2001 +0000
@@ -279,6 +279,8 @@
 struct alias
 {
   struct alias *next;		/* Next in list.  */
+  struct sym *namesp;		/* Namespace in which defined.  */
+  struct link *aliasee;		/* List of aliased namespaces (A::B::C...).  */
   char name[1];			/* Alias name.  */
 };
 
@@ -303,7 +305,6 @@
   char *filename;		/* File in which it can be found.  */
   char *sfilename;		/* File in which members can be found.  */
   struct sym *namesp;		/* Namespace in which defined. .  */
-  struct alias *namesp_aliases;	/* List of aliases for namespaces.  */
   char name[1];                 /* Name of the class.  */
 };
 
@@ -420,6 +421,10 @@
 
 struct member *member_table[TABLE_SIZE];
 
+/* Hash table for namespace aliases */
+
+struct alias *namespace_alias_table[TABLE_SIZE];
+
 /* The special class symbol used to hold global functions,
    variables etc.  */
 
@@ -491,7 +496,7 @@
 void mark_inherited_virtual P_ ((void));
 void leave_namespace P_ ((void));
 void enter_namespace P_ ((char *));
-void register_namespace_alias P_ ((char *, char *));
+void register_namespace_alias P_ ((char *, struct link *));
 void insert_keyword P_ ((char *, int));
 void re_init_scanner P_ ((void));
 void init_scanner P_ ((void));
@@ -508,7 +513,7 @@
 struct member *add_member P_ ((struct sym *, char *, int, int, unsigned));
 void mark_virtual P_ ((struct sym *));
 void mark_virtual P_ ((struct sym *));
-struct sym *make_namespace P_ ((char *));
+struct sym *make_namespace P_ ((char *, struct sym *));
 char *sym_scope P_ ((struct sym *));
 char *sym_scope_1 P_ ((struct sym *));
 int skip_to P_ ((int));
@@ -1085,68 +1090,107 @@
 /* Create and return a symbol for a namespace with name NAME.  */
 
 struct sym *
-make_namespace (name)
+make_namespace (name, context)
      char *name;
+     struct sym *context;
 {
   struct sym *s = (struct sym *) xmalloc (sizeof *s + strlen (name));
   bzero (s, sizeof *s);
   strcpy (s->name, name);
   s->next = all_namespaces;
-  s->namesp = current_namespace;
+  s->namesp = context;
   all_namespaces = s;
   return s;
 }
 
 
+/* Find the symbol for namespace NAME.  If not found, retrun NULL */
+
+struct sym *
+check_namespace (name, context)
+     char *name;
+     struct sym *context;
+{
+  struct sym *p = NULL;
+  
+  for (p = all_namespaces; p; p = p->next)
+    {
+      if (streq (p->name, name) && (p->namesp == context))
+	    break;
+	}
+
+  return p;
+    }
+
 /* Find the symbol for namespace NAME.  If not found, add a new symbol
    for NAME to all_namespaces.  */
 
 struct sym *
-find_namespace (name)
+find_namespace (name, context)
      char *name;
+     struct sym *context;
 {
-  struct sym *p;
-  
-  for (p = all_namespaces; p; p = p->next)
-    {
-      if (streq (p->name, name))
-	break;
-      else
-	{
-	  struct alias *p2;
-	  for (p2 = p->namesp_aliases; p2; p2 = p2->next)
-	    if (streq (p2->name, name))
-	      break;
-	  if (p2)
-	    break;
-	}
-    }
+  struct sym *p = check_namespace (name, context);
 
   if (p == NULL)
-    p = make_namespace (name);
+    p = make_namespace (name, context);
 
   return p;
 }
   
 
-/* Register the name NEW_NAME as an alias for namespace OLD_NAME.  */
+/* Find namespace alias with name NAME. If not found return NULL. */
+
+struct link *
+check_namespace_alias (name)
+    char *name;
+{
+  struct link *p = NULL;
+  struct alias *al;
+  unsigned h;
+  char *s;
+
+  for (s = name, h = 0; *s; ++s)
+    h = (h << 1) ^ *s;
+  h %= TABLE_SIZE;
+
+  for (al = namespace_alias_table[h]; al; al = al->next)
+    if (streq (name, al->name) && (al->namesp == current_namespace))
+      {
+        p = al->aliasee;
+        break;
+      }
+
+  return p;
+}
+
+/* Register the name NEW_NAME as an alias for namespace list OLD_NAME.  */
 
 void
 register_namespace_alias (new_name, old_name)
-     char *new_name, *old_name;
+     char *new_name;
+     struct link *old_name;
 {
-  struct sym *p = find_namespace (old_name);
+  unsigned h;
+  char *s;
   struct alias *al;
 
-  /* Is it already in the list of aliases?  */
-  for (al = p->namesp_aliases; al; al = al->next)
-    if (streq (new_name, p->name))
+  for (s = new_name, h = 0; *s; ++s)
+    h = (h << 1) ^ *s;
+  h %= TABLE_SIZE;
+
+
+  /* Is it already in the table of aliases?  */
+  for (al = namespace_alias_table[h]; al; al = al->next)
+    if (streq (new_name, al->name) && (al->namesp == current_namespace))
       return;
 
   al = (struct alias *) xmalloc (sizeof *al + strlen (new_name));
   strcpy (al->name, new_name);
-  al->next = p->namesp_aliases;
-  p->namesp_aliases = al;
+  al->next = namespace_alias_table[h];
+  al->namesp = current_namespace;
+  al->aliasee = old_name;
+  namespace_alias_table[h] = al;
 }
 
 
@@ -1156,7 +1200,7 @@
 enter_namespace (name)
      char *name;
 {
-  struct sym *p = find_namespace (name);
+  struct sym *p = find_namespace (name, current_namespace);
 
   if (namespace_sp == namespace_stack_size)
     {
@@ -2329,7 +2373,6 @@
   return tk;
 }
 
-
 /* Skip over pairs of tokens (parentheses, square brackets,
    angle brackets, curly brackets) matching the current lookahead.  */
 
@@ -2377,6 +2420,43 @@
 }
 
 
+/* Build qualified namespace alias (A::B::c) and return it. */
+
+struct link *
+match_qualified_namespace_alias ()
+{
+  struct link *head = NULL;
+  struct link *cur = NULL;
+  struct link *tmp = NULL;
+
+  for (;;)
+    {
+      MATCH ();
+      switch (LA1)
+        {
+        case IDENT:
+          tmp = (struct link *) xmalloc (sizeof *cur);
+          tmp->sym = find_namespace (yytext, cur);
+          tmp->next = NULL;
+          if (head)
+            {
+              cur = cur->next = tmp;
+            }
+          else
+            {
+              head = cur = tmp;
+            }
+          break;
+        case DCOLON:
+          /* Just skip */
+          break;
+        default:
+          return head;
+          break;
+        }
+    }
+}
+
 /* Re-initialize the parser by resetting the lookahead token.  */
 
 void
@@ -2913,7 +2993,7 @@
 
 
 /* This one consumes the last IDENT of a qualified member name like
-   `X::Y::z'.  This IDENT is returned in LAST_ID.  Value if the
+   `X::Y::z'.  This IDENT is returned in LAST_ID.  Value is the
    symbol structure for the ident.  */
 
 struct sym *
@@ -2923,6 +3003,7 @@
   struct sym *cls = NULL;
   char *id = NULL;
   size_t id_size = 0;
+  int enter = 0;
   
   while (LOOKING_AT (IDENT))
     {
@@ -2940,7 +3021,26 @@
 
       if (LOOKING_AT (DCOLON))
 	{
-	  cls = add_sym (id, cls);
+	  struct sym *pcn = NULL;
+	  struct link *pna = check_namespace_alias (id);
+	  if (pna)
+	    {
+	      do
+		{
+		  enter_namespace (pna->sym->name);
+		  enter++;
+		  pna = pna->next;
+		}
+	      while (pna);
+	    }
+	  else if ((pcn = check_namespace (id, current_namespace)))
+	    {
+	      enter_namespace (pcn->name);
+	      enter++;
+	    }
+	  else
+	    cls = add_sym (id, cls);
+
 	  *last_id = NULL;
 	  xfree (id);
 	  id = NULL;
@@ -2951,12 +3051,15 @@
 	break;
     }
 
+  while (enter--)
+    leave_namespace();
+
   return cls;
 }
 
 
 /* This one consumes the last IDENT of a qualified member name like
-   `X::Y::z'.  This IDENT is returned in LAST_ID.  Value if the
+   `X::Y::z'.  This IDENT is returned in LAST_ID.  Value is the
    symbol structure for the ident.  */
 
 void
@@ -3310,9 +3413,9 @@
                 
                 if (LOOKING_AT ('='))
                   {
-		    MATCH ();
-		    if (LOOKING_AT (IDENT))
-		      register_namespace_alias (namespace_name, yytext);
+		    struct link *qna = match_qualified_namespace_alias ();
+		    if (qna)
+                      register_namespace_alias (namespace_name, qna);
 		      
                     if (skip_to (';') == ';')
                       MATCH ();
@@ -3536,7 +3639,7 @@
 version ()
 {
   printf ("ebrowse %s\n", VERSION);
-  puts ("Copyright (C) 1992-1999, 2000 Free Software Foundation, Inc.");
+  puts ("Copyright (C) 1992-1999, 2000, 2001 Free Software Foundation, Inc.");
   puts ("This program is distributed under the same terms as Emacs.");
   exit (0);
 }