+#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;
+}
+