diff --git a/lib/modules/String.pmod b/lib/modules/String.pmod
index d2f6f92cd866fb2350c80730edd54acd9eaa16a1..0bde8cf615c9e02d3c6756190e002cab9cb52f0a 100644
--- a/lib/modules/String.pmod
+++ b/lib/modules/String.pmod
@@ -1,5 +1,7 @@
 #define BEGIN 32
 
+constant count=__builtin.string_count;
+
 /*
  * Implode an array of strings to an english 'list'
  * ie. ({"foo","bar","gazonk"}) beomces "foo, bar and gazonk"
diff --git a/src/builtin_functions.c b/src/builtin_functions.c
index 2bd25b9a46468e5c36e3ec6183f77907b2e041c0..b8d4a438fe698b89321a792e0f06067851b90784 100644
--- a/src/builtin_functions.c
+++ b/src/builtin_functions.c
@@ -5,7 +5,7 @@
 \*/
 /**/
 #include "global.h"
-RCSID("$Id: builtin_functions.c,v 1.171 1999/05/13 07:25:38 hubbe Exp $");
+RCSID("$Id: builtin_functions.c,v 1.172 1999/05/25 12:32:51 mirar Exp $");
 #include "interpret.h"
 #include "svalue.h"
 #include "pike_macros.h"
@@ -3965,6 +3965,40 @@ void f_map_array(INT32 args)
   push_array(ret);
 }
 
+void f_string_count(INT32 args)
+{
+   struct pike_string * haystack=NULL;
+   struct pike_string * needle=NULL;
+   int c=0;
+   int i,j;
+
+   get_all_args("String.count",args,"%W%W",&haystack,&needle);
+
+   switch (needle->len)
+   {
+      case 0:
+	 switch (haystack->len)
+	 {
+	    case 0: c=1; break; /* "" appears one time in "" */
+	    case 1: c=0; break; /* "" doesn't appear in "x" */
+	    default: c=haystack->len-1; /* one time between each character */
+	 }
+	 break;
+      case 1:
+	 /* maybe optimize? */
+      default:
+	 for (i=0; i<haystack->len; i++)
+	 {
+	    j=string_search(haystack,needle,i);
+	    if (j==-1) break;
+	    i=j+needle->len-1;
+	    c++;
+	 }
+	 break;
+   }
+   pop_n_elems(args);
+   push_int(c);
+}
 
 void init_builtin_efuns(void)
 {
@@ -4247,6 +4281,7 @@ void init_builtin_efuns(void)
   ADD_FUNCTION("longest_ordered_sequence",f_longest_ordered_sequence,tFunc(tArray,tArr(tInt)),0);
   /* function(array(mixed),array(mixed)...:array(mixed)) */
   ADD_FUNCTION("sort",f_sort,tFuncV(tArr(tMix),tArr(tMix),tArr(tMix)),OPT_SIDE_EFFECT);
+  ADD_FUNCTION("string_count",f_string_count,tFunc(tString tString,tInt),OPT_TRY_OPTIMIZE);
 #ifdef DEBUG_MALLOC
   
 /* function(void:void) */
diff --git a/tutorial/tutorial.wmml b/tutorial/tutorial.wmml
index eb279963438ad142149a964396deb6261aacfeda..671edb3310a973c8a1ed650a214d3e4ba71e0ffd 100644
--- a/tutorial/tutorial.wmml
+++ b/tutorial/tutorial.wmml
@@ -5600,6 +5600,19 @@ as appending 's' to an empty string 'num' times.
 </man_description>
 </function>
 
+<function name=String.count title="count needles in a haystack string">
+<man_syntax>
+string count(string <i>haystack</i>, string <i>needle</i>);
+</man_syntax>
+<man_description>
+This function counts the number of times the needle
+can be found in haystack. 
+
+Intersections between needles are not counted, ie
+count("....","..") is 2.
+</man_description>
+</function>
+
 <hr noshade size=1>
 
 </module>