/* This file contains the regsub() function, which performs substitutions
* after a regexp match has been found.
/* perform substitutions after a regexp match */
void regsub(re
, src
, dst
)
regexp
*re
; /* the regexp with pointers into matched text */
REG
char *src
; /* the replacement string */
REG
char *dst
; /* where to put the result of the subst */
REG
char *cpy
; /* pointer to start of text to copy */
REG
char *end
; /* pointer to end of text to copy */
int mod
= 0;/* used to track \U, \L, \u, \l, and \E */
int len
; /* used to calculate length of subst string */
static char *prev
; /* a copy of the text from the previous subst */
/* replace \~ (or maybe ~) by previous substitution text */
/* step 1: calculate the length of the new substitution text */
for (len
= strlen(src
), c
= '\0', cpy
= src
; *cpy
; cpy
++)
if (c
== '\\' && *cpy
== '~')
if (c
== (*o_magic
? '\0' : '\\') && *cpy
== '~')
regerror("No prev text to substitute for ~");
len
-= 1; /* because we lose the \ too */
/* watch backslash quoting */
if (c
!= '\\' && *cpy
== '\\')
/* allocate memory for the ~ed version of src */
start
= cpy
= (char *)malloc((unsigned)(len
+ 1));
regerror("Not enough memory for ~ expansion");
/* copy src into start, replacing the ~s by the previous text */
if (*o_magic
&& *src
== '~')
else if (!*o_magic
&& *src
== '\\' && *(src
+ 1) == '~')
if (*src
== '\\' && *(src
+ 1) == '~')
if ((int)(cpy
- start
) != len
)
msg("Bug in regsub.c! Predicted length = %d, Actual length = %d", len
, (int)(cpy
- start
));
/* remember this as the "previous" for next time */
#endif /* undef CRUNCH */
while ((c
= *src
++) != '\0')
/* recognize any meta characters */
if (c
== '&' && *o_magic
)
#endif /* not NO_MAGIC */
/* \0 thru \9 mean "copy subexpression" */
/* \U and \L mean "convert to upper/lowercase" */
/* \E ends the \U or \L */
/* "\&" means "original text" */
/* "\&" means "original text" */
/* ordinary char preceded by backslash */
/* transliterate ^M into newline */
/* ordinary character, so just copy it */
/* Note: to reach this point in the code, we must have evaded
* all "continue" statements. To do that, we must have hit
* a metacharacter that involves copying.
/* if there is nothing to copy, loop */
/* copy over a portion of the original */
/* convert to uppercase */
*dst
++ = toupper(*cpy
++);
/* convert to lowercase */
*dst
++ = tolower(*cpy
++);
/* copy without any conversion */
/* \u and \l end automatically after the first char */
if (mod
&& (mod
== 'u' || mod
== 'l'))