From Thomas Eberhardt <thomas@mathematik.uni-Bremen.de>
[unix-history] / usr.bin / elvis / regexp.c
index 96cce7f..2c5383e 100644 (file)
 #include "config.h"
 #include "ctype.h"
 #include "vi.h"
 #include "config.h"
 #include "ctype.h"
 #include "vi.h"
-#include "regexp.h"
+#ifdef REGEX
+# include <regex.h>
+#else
+# include "regexp.h"
+#endif
+
+
+#ifdef REGEX
+extern int patlock;            /* from cmd_substitute() module */
+
+static regex_t *previous = NULL;       /* the previous regexp, used when null regexp is given */
+
+regex_t *
+optpat(s)
+       char *s;
+{
+       char *neuter();
+       char *expand_tilde();
+
+       int n;
+       if (*s == '\0') {
+               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("out of memory");
+               return previous;
+       }
+       patlock = 0;
+       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;
+}
+
+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, *repl;
+       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 (*s == '^')
+               *t++ = *s++;
+       while (*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++;
+       }
+       *t = '\0';
+       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 */
 
 
 static char    *previous;      /* the previous regexp, used when null regexp is given */
 
 
@@ -78,7 +269,7 @@ static char  *retext;        /* points to the text being compiled */
 
 /* error-handling stuff */
 jmp_buf        errorhandler;
 
 /* error-handling stuff */
 jmp_buf        errorhandler;
-#define FAIL(why)      regerror(why); longjmp(errorhandler, 1)
+#define FAIL(why)      regerr(why); longjmp(errorhandler, 1)
 
 
 
 
 
 
@@ -839,7 +1030,7 @@ regexp *regcomp(exp)
 #endif
        if (!re)
        {
 #endif
        if (!re)
        {
-               regerror("Could not malloc a regexp structure");
+               regerr("Could not malloc a regexp structure");
                return (regexp *)0;
        }
 
                return (regexp *)0;
        }
 
@@ -889,7 +1080,7 @@ regexp *regcomp(exp)
                        }
                        else
                        {
                        }
                        else
                        {
-                               regerror("extra \\ at end of regular expression");
+                               regerr("extra \\ at end of regular expression");
                        }
                        break;
 
                        }
                        break;
 
@@ -969,3 +1160,4 @@ int regexec(prog, string, bolflag)
        return rc == 1;
 }
 #endif
        return rc == 1;
 }
 #endif
+#endif /* !REGEX */