home *** CD-ROM | disk | FTP | other *** search
/ Power Programming / powerprogramming1994.iso / progtool / c / string.arc / STRREPL.C < prev    next >
C/C++ Source or Header  |  1984-12-31  |  2KB  |  64 lines

  1. /*  File   : strrepl.c
  2.     Author : Richard A. O'Keefe.
  3.     Updated: 23 April 1984
  4.     Defines: strrepl()
  5.  
  6.     strrepl(dst, src, pat, rep, times) copies src to dst, replacing  the
  7.     first "times" non-overlapping instances of pat by rep.  pat is not a
  8.     regex(3) pattern, it is a  literal  string  which  must  be  matched
  9.     exactly.   As  a  special hack, since strfind claims to find "" just
  10.     once at the end of the src string, strrepl does a strcat when pat is
  11.     an empty string "".  If times <= 0, it is just strmov.
  12.  
  13.     The result is a pointer to the NUL which now terminates dst.
  14.  
  15.     BEWARE: even when rep is shorter than pat it is NOT necessarily safe
  16.     for dst to be the same as src.  ALWAYS make sure dst and src do not/
  17.     will not overlap.  You have been warned.
  18.  
  19.     There really ought to be a strnrepl with a bound for the size of the
  20.     destination string, but there isn't.
  21. */
  22.  
  23. #include "strings.h"
  24. #include "_str2pat.h"
  25.  
  26. char *strrepl(dst, src, pat, rep, times)
  27.     char *dst, *src, *pat, *rep;
  28.     int times;
  29.     {
  30.     register char *s, *p;
  31.     register int c, lastch;
  32.  
  33.     pat = _str2pat(pat);
  34.     if (times <= 0) {
  35.         for (p = dst, s = src; *p++ = *s++; ) ;
  36.         return p-1;
  37.     }
  38.     if (_pat_lim < 0) {
  39.         for (p = dst, s = src; *p++ = *s++; ) ;
  40.         for (--p, s = rep; *p++ = *s++; ) ;
  41.         return p-1;
  42.      }
  43.     /*  The pattern is non-empty and times is positive  */
  44.     c = _pat_lim, lastch = pat[c];
  45.     for (;;) {
  46.         for (s = src, p = dst; --c >= 0; )
  47.         if (!(*p++ = *s++)) return p-1;
  48.         c = *s, src = s, dst = p;
  49.         if (c == lastch) {
  50.         for (s -= _pat_lim, p = pat; *p; )
  51.             if (*s++ != *p++) goto not_yet;
  52.         for (p = dst-_pat_lim, s = rep; *p++ = *s++; ) ;
  53.         --p;
  54.         if (--times == 0) {
  55.             for (s = src; *p++ = *++s; ) ;
  56.             return p-1;
  57.         }
  58.         dst = p, src++, c = _pat_lim;
  59.         } else {
  60. not_yet:    c = _pat_vec[c];
  61.         }
  62.     }
  63.     }