From 79157a03fda7b559b62e583c4e0735c0246812e6 Mon Sep 17 00:00:00 2001
From: hniksic <devnull@localhost>
Date: Mon, 15 Sep 2003 03:47:46 -0700
Subject: [PATCH] [svn] Made strpbrk_or_eos a macro under Gcc.

---
 src/ChangeLog |  4 ++++
 src/url.c     | 22 +++++++++++++++++++++-
 2 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 8d358383..643d0ba1 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2003-09-15  Hrvoje Niksic  <hniksic@xemacs.org>
+
+	* url.c (strpbrk_or_eos): Implement as a macro under Gcc.
+
 2003-09-15  Hrvoje Niksic  <hniksic@xemacs.org>
 
 	* cookies.c (parse_set_cookies): Allow trailing space in
diff --git a/src/url.c b/src/url.c
index 3a8feb70..9776cc3e 100644
--- a/src/url.c
+++ b/src/url.c
@@ -616,7 +616,26 @@ static void parse_path PARAMS ((const char *, char **, char **));
 
 /* Like strpbrk, with the exception that it returns the pointer to the
    terminating zero (end-of-string aka "eos") if no matching character
-   is found.  */
+   is found.
+
+   Although I normally balk at Gcc-specific optimizations, it probably
+   makes sense here: glibc has optimizations that detect strpbrk being
+   called with literal string as ACCEPT and inline the search.  That
+   optimization is defeated if strpbrk is hidden within the call to
+   another function.  (And no, making strpbrk_or_eos inline doesn't
+   help because the check for literal accept is in the
+   preprocessor.)  */
+
+#ifdef __GNUC__
+
+#define strpbrk_or_eos(s, accept) ({		\
+  char *SOE_p = strpbrk (s, accept);		\
+  if (!SOE_p)					\
+    SOE_p = (char *)s + strlen (s);		\
+  SOE_p;					\
+})
+
+#else  /* not __GNUC__ */
 
 static char *
 strpbrk_or_eos (const char *s, const char *accept)
@@ -626,6 +645,7 @@ strpbrk_or_eos (const char *s, const char *accept)
     p = (char *)s + strlen (s);
   return p;
 }
+#endif
 
 /* Turn STR into lowercase; return non-zero if a character was
    actually changed. */