From a1640e16f6d90747024dac6dba288a4a32851f71 Mon Sep 17 00:00:00 2001
From: Marcus Comstedt <marcus@mc.pp.se>
Date: Sat, 18 Sep 2010 13:56:55 +0200
Subject: [PATCH] Allow integer constants exported by modules to be used in cpp
 expressions.

Rev: CHANGES:1.214
Rev: src/cpp.c:1.179
Rev: src/preprocessor.h:1.96
---
 CHANGES            |  2 ++
 src/cpp.c          | 50 +++++++++++++++++++++++++++++++---------------
 src/preprocessor.h | 27 ++++++++++++++++++++++++-
 3 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/CHANGES b/CHANGES
index c135169a12..b579bd8aa9 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 6801e20a91..1606004a13 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 a80bf8dae7..874d705132 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);
-- 
GitLab