diff --git a/CHANGES b/CHANGES
index c135169a128643249b07ef3e89ef9b3662764499..b579bd8aa9a54cc81371896d0c77d059a7c4c8d0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -29,6 +29,8 @@ o Protocols.HTTP
 
 o Tools.PV and pike -x pv now works with GTK2 as well as GTK.
 
+o Integer constants exported by modules can now be used in cpp expressions.
+
 
 Deprecations
 ------------
diff --git a/src/cpp.c b/src/cpp.c
index 6801e20a914c774a51a946ead91ef80115c15562..1606004a1377a94be2dd569fcff5fc51e821ff47 100644
--- a/src/cpp.c
+++ b/src/cpp.c
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: cpp.c,v 1.178 2010/07/27 16:46:02 mast Exp $
+|| $Id: cpp.c,v 1.179 2010/09/18 11:56:50 marcus Exp $
 */
 
 #include "global.h"
@@ -557,25 +557,13 @@ static int do_safe_index_call(struct cpp *this, struct pike_string *s)
   return res;
 }
 
-void cpp_func_constant(struct cpp *this, INT32 args)
+static void cpp_low_constant(struct cpp *this, int value)
 {
   struct svalue *save_stack=sp;
   struct array *arr;
-  int res = 0;
+  INT_TYPE res = 0;
   int n;
 
-  if (args != 1) {
-    cpp_error(this, "Bad number of arguments to constant().");
-    pop_n_elems(args);
-    push_int(0);
-    return;
-  }
-#ifdef PIKE_DEBUG
-  if (Pike_sp[-1].type != T_STRING) {
-    Pike_fatal("Bad argument 1 to constant(): %s (expected string).\n",
-	       get_name_of_type(Pike_sp[-1].type));
-  }
-#endif /* PIKE_DEBUG */
   /* FIXME: Protection against errors. */
   /* Remove extra whitespace. */
   push_constant_text(" ");
@@ -672,10 +660,40 @@ void cpp_func_constant(struct cpp *this, INT32 args)
     res = do_safe_index_call(this, arr->item[n].u.string);
   }
 
-  pop_n_elems(args + sp - save_stack);
+  if (value && res) {
+    if (sp[-1].type == T_INT)
+      res = sp[-1].u.integer;
+    else
+      res = 0;
+  }
+
+  pop_n_elems(1 + sp - save_stack);
   push_int(res);
 }
 
+void cpp_func_constant(struct cpp *this, INT32 args)
+{
+  if (args != 1) {
+    cpp_error(this, "Bad number of arguments to constant().");
+    pop_n_elems(args);
+    push_int(0);
+    return;
+  }
+#ifdef PIKE_DEBUG
+  if (Pike_sp[-1].type != T_STRING) {
+    Pike_fatal("Bad argument 1 to constant(): %s (expected string).\n",
+	       get_name_of_type(Pike_sp[-1].type));
+  }
+#endif /* PIKE_DEBUG */
+  cpp_low_constant(this, 0);
+}
+
+void cpp_resolv_constant(struct cpp *this, struct pike_string *identifier)
+{
+  ref_push_string (identifier);
+  cpp_low_constant(this, 1);
+}
+
 /* Macro handling. */
 
 static struct mapping *initial_predefs_mapping(void)
diff --git a/src/preprocessor.h b/src/preprocessor.h
index a80bf8dae73c536b80c515cbd3223e60bc3e786d..874d705132c10ac1acf296baeb2c2b9a62776658 100644
--- a/src/preprocessor.h
+++ b/src/preprocessor.h
@@ -2,7 +2,7 @@
 || This file is part of Pike. For copyright information see COPYRIGHT.
 || Pike is distributed under GPL, LGPL and MPL. See the file COPYING
 || for more information.
-|| $Id: preprocessor.h,v 1.95 2008/06/29 21:14:00 marcus Exp $
+|| $Id: preprocessor.h,v 1.96 2010/09/18 11:56:55 marcus Exp $
 */
 
 /*
@@ -610,6 +610,31 @@ static ptrdiff_t calcC(struct cpp *this, WCHAR *data, ptrdiff_t len,
 	  cpp_func(this, arg);
 	else
 	  pop_n_elems(arg);
+      } else if (data[pos] == '.') {
+	while (GOBBLE('.')) {
+	  struct pike_string *ind_name;
+	  SKIPWHITE();
+	  ind_name = GOBBLE_IDENTIFIER();
+	  if (ind_name == NULL) {
+	    cpp_error_sprintf(this, "Syntax error in #if missing identifier after '.'.");
+	    free_string (func_name);
+	    func_name = NULL;
+	    break;
+	  }
+	  if(OUTP()) {
+	    push_string (func_name);
+	    push_text (".");
+	    push_string (ind_name);
+	    f_add(3);
+	    func_name = Pike_sp[-1].u.string;
+	    --Pike_sp;
+	  }
+	  SKIPWHITE();
+	}
+	if (func_name == NULL)
+	  break;
+	if(OUTP())
+	  cpp_resolv_constant(this, func_name);
       } else {
 	if(OUTP())
 	  push_int(0);