aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/elvis/regexp.c
diff options
context:
space:
mode:
authorsvn2git <svn2git@FreeBSD.org>1994-05-01 08:00:00 +0000
committersvn2git <svn2git@FreeBSD.org>1994-05-01 08:00:00 +0000
commita16f65c7d117419bd266c28a1901ef129a337569 (patch)
tree2626602f66dc3551e7a7c7bc9ad763c3bc7ab40a /usr.bin/elvis/regexp.c
parent8503f4f13f77abf7adc8f7e329c6f9c1d52b6a20 (diff)
Diffstat (limited to 'usr.bin/elvis/regexp.c')
-rw-r--r--usr.bin/elvis/regexp.c156
1 files changed, 144 insertions, 12 deletions
diff --git a/usr.bin/elvis/regexp.c b/usr.bin/elvis/regexp.c
index 43a8672a1354..2c5383e716f1 100644
--- a/usr.bin/elvis/regexp.c
+++ b/usr.bin/elvis/regexp.c
@@ -49,45 +49,120 @@ regex_t *
optpat(s)
char *s;
{
- static char *neuter();
+ char *neuter();
+ char *expand_tilde();
int n;
if (*s == '\0') {
- if (!previous) regerr("RE error: no previous pattern");
+ if (!previous) regerr("no previous pattern");
return previous;
} else if (previous && !patlock)
regfree(previous);
else if ((previous = (regex_t *) malloc(sizeof(regex_t))) == NULL) {
- regerr("RE error: out of memory");
+ regerr("out of memory");
return previous;
}
patlock = 0;
- if (n = regcomp(previous, *o_magic ? s : neuter(s),
- *o_ignorecase ? REG_ICASE : 0)) {
- regerr("RE error: %d", n);
+ if ((s = *o_magic ? expand_tilde(s) : neuter(s)) == NULL) {
+ free(previous);
+ return previous = NULL;
+ } else if (n = regcomp(previous, s, *o_ignorecase ? REG_ICASE : 0)) {
+ regerr("%d", n);
free(previous);
return previous = NULL;
}
return previous;
}
-/* escape BRE meta-characters in a string */
-static char *
+extern char *last_repl; /* replacement text from previous substitute */
+
+/* expand_tilde: expand ~'s in a BRE */
+char *
+expand_tilde(s)
+ char *s;
+{
+ char *literalize();
+ static char *hd = NULL;
+
+ char *t, *repl;
+ int size;
+ int offset;
+ int m;
+
+ free(hd);
+ hd = t = malloc(size = strlen(s) + 1);
+ while (*s)
+ if (*s == '\\' && *(s + 1) == '~') {
+ *t++ = *s++;
+ *t++ = *s++;
+ } else if (*s != '~')
+ *t++ = *s++;
+ else {
+ if (!last_repl) {
+ regerr("no previous replacement");
+ return NULL;
+ } else if ((repl = literalize(last_repl)) == NULL)
+ return NULL;
+ m = strlen(repl);
+ offset = t - hd;
+ if ((hd = realloc(hd, size += m)) == NULL) {
+ regerr("out of memory");
+ return NULL;
+ }
+ t = hd + offset;
+ strcpy(t, repl);
+ t += m;
+ s++;
+ }
+ *t = '\0';
+ return hd;
+}
+
+
+/* escape BRE meta-characters and expand ~'s in a string */
+char *
neuter(s)
char *s;
{
+ char *literalize();
static char *hd = NULL;
- char *t;
- int n = strlen(s);
+ char *t, *repl;
+ int size;
+ int offset;
+ int m;
free(hd);
- if ((hd = t = (char *) malloc(n + n + 1)) == NULL)
+ if ((hd = t = (char *) malloc(size = 2 * strlen(s) + 1)) == NULL) {
+ regerr("out of memory");
return NULL;
+ }
if (*s == '^')
*t++ = *s++;
while (*s) {
- if (*s == '.' || *s == '\\' || *s == '[' || *s == '*')
+ if (*s == '\\' && (*(s + 1) == '.' || *(s + 1) == '*' ||
+ *(s + 1) == '[')) {
+ s++;
+ *t++ = *s++;
+ continue;
+ } else if (*s == '\\' && *(s + 1) == '~') {
+ if (!last_repl) {
+ regerr("no previous replacement");
+ return NULL;
+ } else if ((repl = literalize(last_repl)) == NULL)
+ return NULL;
+ m = strlen(repl);
+ offset = t - hd;
+ if ((hd = realloc(hd, size += m)) == NULL) {
+ regerr("out of memory");
+ return NULL;
+ }
+ t = hd + (offset);
+ strcpy(t, repl);
+ t += m;
+ s += 2;
+ continue;
+ } else if (*s == '.' || *s == '\\' || *s == '[' || *s == '*')
*t++ = '\\';
*t++ = *s++;
}
@@ -95,6 +170,63 @@ neuter(s)
return hd;
}
+
+/* escape BRE meta-characters in a string */
+char *
+literalize(s)
+ char *s;
+{
+ static char *hd = NULL;
+
+ char *t;
+ int size;
+ int offset;
+ int m;
+
+ free(hd);
+ if ((hd = t = (char *) malloc(size = 2 * strlen(s) + 1)) == NULL) {
+ regerr("out of memory");
+ return NULL;
+ }
+ if (*o_magic)
+ while (*s) {
+ if (*s == '~' || *s == '&') {
+ regerr("can't use ~ or & in pattern");
+ return NULL;
+ } else if (*s == '\\') {
+ s++;
+ if (isdigit(*s)) {
+ regerr("can't use \\d in pattern");
+ return NULL;
+ } else if (*s == '&' || *s == '~') {
+ *t++ = '\\';
+ *t++ = *s++;
+ }
+ } else if (*s == '^' || *s == '$' || *s == '.' ||
+ *s == '[' || *s == '*') {
+ *t++ = '\\';
+ *t++ = *s++;
+ } else
+ *t++ = *s++;
+ }
+ else
+ while (*s) {
+ if (*s == '\\') {
+ s++;
+ if (*s == '&' || *s == '~') {
+ regerr("can't use \\~ or \\& in pattern");
+ return NULL;
+ } else if (isdigit(*s)) {
+ regerr("can't use \\d in pattern");
+ return NULL;
+ }
+ } else
+ *t++ = *s++;
+ }
+ *t = '\0';
+ return hd;
+}
+
#else
static char *previous; /* the previous regexp, used when null regexp is given */