Short: New efun replace_string()
From: Daniel Sloan
Date: 990410
Type: Patch
State Unclassified

diff-replace : A diff for the efun 'replace_string()', which does the same as
               implode(explode(X, Y), Z);, but does it faster and without
               creating an array, of course :-)

diff -rc ldmud-dev/src/func_spec ldmud-dev-rep/src/func_spec
*** ldmud-dev/src/func_spec	Sat Mar 27 14:27:43 1999
--- ldmud-dev-rep/src/func_spec	Sat Apr 10 15:45:03 1999
***************
*** 374,379 ****
--- 375,381 ----
  void  set_extra_wizinfo_size(int);
  int caller_stack(int default: F_CONST0);
  int caller_stack_depth();
+ string replace_string(string, string, string);

  /* A few interesting comm functions for the internet mud protocol */
  #ifdef MAXNUMPORTS
diff -rc ldmud-dev/src/interpret.c ldmud-dev-rep/src/interpret.c
*** ldmud-dev/src/interpret.c	Wed Mar 31 12:28:11 1999
--- ldmud-dev-rep/src/interpret.c	Sat Apr 10 15:44:55 1999
***************
*** 9338,9343 ****
--- 9338,9410 ----
              pc = current_prog->program + offset[0];
              break;
            }
+ #ifdef F_REPLACE_STRING
+ 	  XCASE(F_REPLACE_STRING);
+ 	  {
+ 	      int slen, dlen, rlen;
+ 	      char *str, *del, *rep;
+ 	      char *buff, *ptr;
+ 	      int n, i;
+
+ 	      TYPE_TEST1(sp-2, T_STRING)
+ 	      TYPE_TEST2(sp-1, T_STRING)
+ 	      TYPE_TEST3(sp, T_STRING)
+
+ 	      str = (sp-2)->u.string;
+ 	      del = (sp-1)->u.string;
+ 	      rep = (sp)->u.string;
+
+ 	      slen = strlen(str);
+ 	      dlen = strlen(del);
+ 	      rlen = strlen(rep);
+
+ 	      if (!slen || !dlen)
+ 	      {
+ 		  buff = string_copy(str);
+ 		  goto replace_string_end; /* I hate goto :-/ */
+ 	      }
+
+ 	      for (n = i = 0; i < slen;)
+ 	      {
+ 		  if (i + dlen <= slen && !memcmp(str + i, del, dlen))
+ 		  {
+ 		      n++;
+ 		      i += dlen;
+ 		  }
+ 		  else
+ 		  {
+ 		      i++;
+ 		  }
+ 	      }
+ 	      if (!n)
+ 	      {
+ 		  buff = string_copy(str);
+ 		  goto replace_string_end;
+ 	      }
+
+ 	      ptr = buff = (char *)xalloc(slen + n * (rlen - dlen) + 1);
+
+ 	      for (i = 0; i < slen;)
+ 	      {
+ 		  if (i + dlen <= slen && !memcmp(str + i, del, dlen))
+ 		  {
+ 		      memcpy(ptr, rep, rlen);
+ 		      i += dlen;
+ 		      ptr += rlen;
+ 		  }
+ 		  else
+ 		  {
+ 		      *(ptr++) = str[i++];
+ 		  }
+ 	      }
+ 	      buff[slen + n * (rlen - dlen)] = '\0';
+
+ replace_string_end:
+ 	      pop_n_elems(3);
+ 	      push_malloced_string(buff);
+ 	      break;
+ 	  }
+ #endif
            XCASE(F_PROGRAM_NAME);
            {
                char *name, *res;
