From f34f648a5feb8117623d1211e287994f69a03b94 Mon Sep 17 00:00:00 2001
From: Martin Stjernholm <mast@lysator.liu.se>
Date: Sun, 5 May 2002 18:31:08 +0200
Subject: [PATCH] Implemented global.Foo to be able to resolve the module Foo
 even when there is a local identifier with that name.

Rev: src/language.yacc:1.277
Rev: src/program.c:1.423
Rev: src/program.h:1.157
Rev: src/testsuite.in:1.510
---
 src/language.yacc |  9 +++++++-
 src/program.c     | 29 +++++++++++++++----------
 src/program.h     |  3 ++-
 src/testsuite.in  | 55 +++++++++++++++++++++++++++++++++++++++++++++--
 4 files changed, 81 insertions(+), 15 deletions(-)

diff --git a/src/language.yacc b/src/language.yacc
index 88c2f86dd1..56ff373b6b 100644
--- a/src/language.yacc
+++ b/src/language.yacc
@@ -113,7 +113,7 @@
 /* This is the grammar definition of Pike. */
 
 #include "global.h"
-RCSID("$Id: language.yacc,v 1.276 2002/05/05 13:03:42 mast Exp $");
+RCSID("$Id: language.yacc,v 1.277 2002/05/05 16:31:06 mast Exp $");
 #ifdef HAVE_MEMORY_H
 #include <memory.h>
 #endif
@@ -3258,6 +3258,13 @@ idents: low_idents
     copy_shared_string(Pike_compiler->last_identifier, $2->u.sval.u.string);
     free_node($2);
   }
+  | TOK_GLOBAL '.' TOK_IDENTIFIER
+  {
+    $$ = resolve_identifier ($3->u.sval.u.string);
+    if(Pike_compiler->last_identifier) free_string(Pike_compiler->last_identifier);
+    copy_shared_string(Pike_compiler->last_identifier, $3->u.sval.u.string);
+    free_node ($3);
+  }
   | idents '.' bad_identifier {}
   | idents '.' error {}
   ;
diff --git a/src/program.c b/src/program.c
index 5e41fb8373..43c0ee04c2 100644
--- a/src/program.c
+++ b/src/program.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: program.c,v 1.422 2002/05/01 21:25:55 mast Exp $");
+RCSID("$Id: program.c,v 1.423 2002/05/05 16:31:07 mast Exp $");
 #include "program.h"
 #include "object.h"
 #include "dynamic_buffer.h"
@@ -950,6 +950,8 @@ static struct node_s *index_modules(struct pike_string *ident,
   return 0;
 }
 
+struct node_s *resolve_identifier(struct pike_string *ident);
+
 struct node_s *find_module_identifier(struct pike_string *ident,
 				      int see_inherit)
 {
@@ -1014,6 +1016,13 @@ struct node_s *find_module_identifier(struct pike_string *ident,
     return mkconstantsvaluenode(&s);
   }
 
+  return resolve_identifier(ident);
+}
+
+struct node_s *resolve_identifier(struct pike_string *ident)
+{
+  struct node_s *ret;
+
   if(resolve_cache)
   {
     struct svalue *tmp=low_mapping_string_lookup(resolve_cache,ident);
@@ -3197,11 +3206,10 @@ PMOD_EXPORT int quick_map_variable(char *name,
 
 #ifdef PROGRAM_BUILD_DEBUG
   {
-    fprintf (stderr, "%.*sdefining variable (pass=%d): ",
-	     compilation_depth, "                ", Pike_compiler->compiler_pass);
-    push_string (describe_type (t));
-    print_svalue (stderr, Pike_sp - 1);
-    pop_stack();
+    struct pike_string *d = describe_type (t);
+    fprintf (stderr, "%.*sdefining variable (pass=%d): %s ",
+	     compilation_depth, "                ", Pike_compiler->compiler_pass, d->str);
+    free_string (d);
     push_string (n);
     print_svalue (stderr, --Pike_sp);
     putc ('\n', stderr);
@@ -3228,11 +3236,10 @@ int define_variable(struct pike_string *name,
 
 #ifdef PROGRAM_BUILD_DEBUG
   {
-    fprintf (stderr, "%.*sdefining variable (pass=%d): ",
-	     compilation_depth, "                ", Pike_compiler->compiler_pass);
-    push_string (describe_type (type));
-    print_svalue (stderr, Pike_sp - 1);
-    pop_stack();
+    struct pike_string *d = describe_type (type);
+    fprintf (stderr, "%.*sdefining variable (pass=%d): %s ",
+	     compilation_depth, "                ", Pike_compiler->compiler_pass, d->str);
+    free_string (d);
     push_string (name);
     print_svalue (stderr, --Pike_sp);
     putc ('\n', stderr);
diff --git a/src/program.h b/src/program.h
index 57fb4cd65b..279dcbf72f 100644
--- a/src/program.h
+++ b/src/program.h
@@ -5,7 +5,7 @@
 \*/
 
 /*
- * $Id: program.h,v 1.156 2002/04/09 10:33:56 mast Exp $
+ * $Id: program.h,v 1.157 2002/05/05 16:31:07 mast Exp $
  */
 #ifndef PROGRAM_H
 #define PROGRAM_H
@@ -452,6 +452,7 @@ void use_module(struct svalue *s);
 void unuse_modules(INT32 howmany);
 struct node_s *find_module_identifier(struct pike_string *ident,
 				      int see_inherit);
+struct node_s *resolve_identifier(struct pike_string *ident);
 struct program *parent_compilation(int level);
 struct program *id_to_program(INT32 id);
 void optimize_program(struct program *p);
diff --git a/src/testsuite.in b/src/testsuite.in
index 42cd720153..200dba5067 100644
--- a/src/testsuite.in
+++ b/src/testsuite.in
@@ -1,4 +1,4 @@
-test_true([["$Id: testsuite.in,v 1.509 2002/05/05 13:03:42 mast Exp $"]]);
+test_true([["$Id: testsuite.in,v 1.510 2002/05/05 16:31:08 mast Exp $"]]);
 
 cond([[all_constants()->_verify_internals]],
 [[
@@ -2143,7 +2143,19 @@ test_program([[
   int a() {return X()->Y()->f() == "XAYBB";}
 ]])
 
-// Testing global::
+test_program([[
+  class A {
+    string s = "A";
+  }
+  inherit A;
+  class X {
+    constant s = "X";
+    mixed f (string s) {return s + X::s + A::s;}
+  }
+  int a() {return X()->f("L") == "LXA";}
+]])
+
+// Testing 'global::'
 
 test_equal([[
   compile_string (#"
@@ -2177,6 +2189,45 @@ test_equal([[
     }")()->X()->f (33);
 ]], ({23, 24, 32, 33}))
 
+// Testing 'global.'
+
+test_compile([[
+  mixed a() {return global.Parser.HTML;}
+]], 0);
+
+test_compile_error([[
+  #pike 7.2
+  mixed a() {return global.Parser.HTML;}
+]], 0);
+
+test_any([[
+  if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n");
+  return compile_string (#"
+    class Parser {constant HTML = 1;}
+    mixed foo() {return programp (Parser.HTML);}")()->foo();
+]], 0);
+
+test_any([[
+  if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n");
+  return compile_string (#"
+    mixed foo() {return programp (Parser.HTML);}
+    class Parser {constant HTML = 1;}")()->foo();
+]], 0);
+
+test_any([[
+  if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n");
+  return compile_string (#"
+    class Parser {constant HTML = 1;}
+    mixed foo() {return programp (global.Parser.HTML);}")()->foo();
+]], 1);
+
+test_any([[
+  if (!programp (Parser.HTML)) error ("This test uses the existence of Parser.HTML.\n");
+  return compile_string (#"
+    mixed foo() {return programp (global.Parser.HTML);}
+    class Parser {constant HTML = 1;}")()->foo();
+]], 1);
+
 // testing virtual overloading
 test_any([[
 class fnord
-- 
GitLab