Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
PATCH: =~ regex match
- X-seq: zsh-workers 23327
- From: Phil Pennock <zsh-workers+phil.pennock@xxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxx
- Subject: PATCH: =~ regex match
- Date: Wed, 25 Apr 2007 21:19:38 -0700
- Domainkey-signature: a=rsa-sha1; q=dns; c=nofws; s=first1; d=spodhuis.org; h=Received:Date:From:To:Subject:Message-ID:Mail-Followup-To:MIME-Version:Content-Type:Content-Disposition; b=ffuDXN78cD+mgZ/tq48wfk1E8G12BFBQSXzk2aRNHSIRU5bNHhhjEPPp4RnSWqF0GYJLH2BgPWKfDb2FojeoTRrPZB36eLOtf68ZMQzEw2XxHcxhzjAoriw14WQoQE+sqx9pwoVCxc1OMGAOFQiiFc9QDHo2YGpI6i8lWCETdMs=;
- Mail-followup-to: zsh-workers@xxxxxxxxxx
- Mailing-list: contact zsh-workers-help@xxxxxxxxxx; run by ezmlm
My mental processes push me towards regexps perhaps more than is
healthy. zsh/pcre's -pcre-match conditional operator is firmly in my
toolkit.
Earlier today I discovered that bash has a =~ operator for doing
extended regexp comparisons. I became envious, so I did something about
it. Which didn't involve giving up all the conveniences of zsh which
have spoiled me.
The below patch makes =~ an operator which silently auto-loads zsh/pcre
and uses -pcre-match from there. This is not bash-compatible in that:
1: it's PCRE -- far more to my liking :^)
2: if the regexp pattern is bad, it returns false/1 not false/2.
Further, I became aware of =~ because someone was ranting about bash3.2
breaking their scripts by insisting that the regexp must not be quoted.
zsh's =~ is more compatible with older bash scripts by accepting either.
The Src/cond.c @@ -139,7 +153,8 @@ patch covers a case where a bug in my
developing exposed a bug in zsh's internal-protection error handling,
whereby the else condition of an "if non-null and other condition"
assumed the non-null aspect.
My uncovering that bug does more to demonstrate how little I understand
things, so if there are other issues, please do let me know.
This =~ will return an error cleanly if zsh/pcre is not available for
whatever reason.
Index: Src/cond.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/cond.c,v
retrieving revision 1.8
diff -p -u -r1.8 cond.c
--- Src/cond.c 30 May 2006 22:35:03 -0000 1.8
+++ Src/cond.c 26 Apr 2007 04:05:18 -0000
@@ -34,7 +34,7 @@ int tracingcond;
static char *condstr[COND_MOD] = {
"!", "&&", "||", "==", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
- "-ne", "-lt", "-gt", "-le", "-ge"
+ "-ne", "-lt", "-gt", "-le", "-ge", "=~"
};
/*
@@ -53,14 +53,14 @@ int
evalcond(Estate state, char *fromtest)
{
struct stat *st;
- char *left, *right;
+ char *left, *right, *overridename;
Wordcode pcode;
wordcode code;
int ctype, htok = 0, ret;
rec:
- left = right = NULL;
+ left = right = overridename = NULL;
pcode = state->pc++;
code = *pcode;
ctype = WC_COND_TYPE(code);
@@ -92,13 +92,27 @@ evalcond(Estate state, char *fromtest)
state->pc = pcode + (WC_COND_SKIP(code) + 1);
return ret;
}
+ case COND_REGEX:
+ {
+ int loaded;
+ loaded = load_module_silence("zsh/pcre", 1);
+ if (!loaded) {
+ zwarnnam(fromtest, "zsh/pcre not available for regex");
+ return 2;
+ }
+ ctype = COND_MODI;
+ overridename = "-pcre-match";
+ }
case COND_MOD:
case COND_MODI:
{
Conddef cd;
- char *name = ecgetstr(state, EC_NODUP, NULL), **strs;
+ char *name = overridename;
+ char **strs;
int l = WC_COND_SKIP(code);
+ if (name == NULL)
+ name = ecgetstr(state, EC_NODUP, NULL);
if (ctype == COND_MOD)
strs = ecgetarr(state, l, EC_DUP, NULL);
else {
@@ -139,7 +153,8 @@ evalcond(Estate state, char *fromtest)
return !cd->handler(strs, cd->condid);
} else {
zwarnnam(fromtest,
- "unrecognized condition: `%s'", name);
+ "unrecognized condition: `%s'",
+ name ? name : "<null>");
}
}
/* module not found, error */
Index: Src/parse.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/parse.c,v
retrieving revision 1.64
diff -p -u -r1.64 parse.c
--- Src/parse.c 23 Apr 2007 17:24:23 -0000 1.64
+++ Src/parse.c 26 Apr 2007 04:05:19 -0000
@@ -2124,6 +2124,12 @@ par_cond_triple(char *a, char *b, char *
ecstr(a);
ecstr(c);
ecadd(ecnpats++);
+ } else if ((b[0] == Equals || b[0] == '=') &&
+ (b[1] == '~' || b[1] == Tilde) && ~b[2]) {
+ ecadd(WCB_COND(COND_REGEX, 0));
+ ecstr(a);
+ ecstr(c);
+ ecadd(ecnpats++);
} else if (b[0] == '-') {
if ((t0 = get_cond_num(b + 1)) > -1) {
ecadd(WCB_COND(t0 + COND_NT, 0));
Index: Src/text.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/text.c,v
retrieving revision 1.19
diff -p -u -r1.19 text.c
--- Src/text.c 23 Apr 2007 15:24:00 -0000 1.19
+++ Src/text.c 26 Apr 2007 04:05:19 -0000
@@ -640,7 +640,7 @@ gettext2(Estate state)
{
static char *c1[] = {
"=", "!=", "<", ">", "-nt", "-ot", "-ef", "-eq",
- "-ne", "-lt", "-gt", "-le", "-ge"
+ "-ne", "-lt", "-gt", "-le", "-ge", "=~"
};
int ctype;
@@ -724,7 +724,7 @@ gettext2(Estate state)
}
break;
default:
- if (ctype <= COND_GE) {
+ if (ctype < COND_MOD) {
/* Binary test: `a = b' etc. */
taddstr(ecgetstr(state, EC_NODUP, NULL));
taddstr(" ");
Index: Src/zsh.h
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.h,v
retrieving revision 1.112
diff -p -u -r1.112 zsh.h
--- Src/zsh.h 29 Mar 2007 21:35:39 -0000 1.112
+++ Src/zsh.h 26 Apr 2007 04:05:22 -0000
@@ -519,8 +519,9 @@ struct timedfn {
#define COND_GT 13
#define COND_LE 14
#define COND_GE 15
-#define COND_MOD 16
-#define COND_MODI 17
+#define COND_REGEX 16
+#define COND_MOD 17
+#define COND_MODI 18
typedef int (*CondHandler) _((char **, int));
Index: Src/Modules/pcre.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/pcre.c,v
retrieving revision 1.11
diff -p -u -r1.11 pcre.c
--- Src/Modules/pcre.c 5 Apr 2007 16:20:15 -0000 1.11
+++ Src/Modules/pcre.c 26 Apr 2007 04:05:22 -0000
@@ -173,6 +173,10 @@ cond_pcre_match(char **a, int id)
switch(id) {
case CPCRE_PLAIN:
pcre_pat = pcre_compile(rhre, pcre_opts, &pcre_err, &pcre_errptr, NULL);
+ if (pcre_pat == NULL) {
+ zwarn("failed to compile regexp: %s", rhre);
+ return 0;
+ }
pcre_fullinfo(pcre_pat, NULL, PCRE_INFO_CAPTURECOUNT, &capcnt);
ovsize = (capcnt+1)*3;
ov = zalloc(ovsize*sizeof(int));
@@ -191,6 +195,7 @@ cond_pcre_match(char **a, int id)
static struct conddef cotab[] = {
CONDDEF("pcre-match", CONDF_INFIX, cond_pcre_match, 0, 0, CPCRE_PLAIN)
+ /* CONDDEF can register =~ but it won't be found */
};
/**/
Messages sorted by:
Reverse Date,
Date,
Thread,
Author