summaryrefslogtreecommitdiff
path: root/hook.c
diff options
context:
space:
mode:
authorPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-03-11 21:48:39 -0300
committerPaulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>2008-07-02 19:05:05 -0300
commit953664369cc66ba17c7b9c1939fd9d7f6c6137ad (patch)
tree1cb6eb5ec3a97d8e8ee0a250b74a32018a84f65e /hook.c
parenta2c47d3487aaf4667926195ba3f5b05b94626daf (diff)
Fix several problems in the line edit mode.
Also allow replacing control characters in the replace pattern as well as nul characters.
Diffstat (limited to 'hook.c')
-rw-r--r--hook.c149
1 files changed, 91 insertions, 58 deletions
diff --git a/hook.c b/hook.c
index 87f0da6..8d2eb22 100644
--- a/hook.c
+++ b/hook.c
@@ -70,6 +70,8 @@ typedef struct _EditInfo {
/* String and flags used to compile regex */
char pattern[64];
+ char subst_pattern[64];
+ int pat_length;
int flags;
/* Substitution buffer */
@@ -383,7 +385,7 @@ LineEditAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
{
XawTextBlock block;
- if (True) {
+ if (international) {
/* XXX FIXME */
fprintf(stderr, "LineEditAction: Not working in international mode.\n");
return;
@@ -400,10 +402,6 @@ LineEditAction(Widget w, XEvent *event, String *params, Cardinal *num_params)
line_edit = True;
}
-#define LSCAN(from, count, include) \
- XawTextSourceScan(source, from, XawstEOL, XawsdLeft, count, include)
-#define RSCAN(from, count, include) \
- XawTextSourceScan(source, from, XawstEOL, XawsdRight, count, include)
void
LineEdit(Widget w)
{
@@ -757,8 +755,9 @@ LineEdit(Widget w)
/* Need to (re)compile regular expression pattern? */
if ((!!(einfo.flags & RE_ICASE) ^ icase) ||
- strlen(einfo.pattern) < length ||
- strncmp(pstart, einfo.pattern, length)) {
+ einfo.pat_length != length ||
+ memcmp(pstart, einfo.pattern,
+ length > einfo.pat_length ? einfo.pat_length : length)) {
compile = 1;
memcpy(einfo.pattern, pstart, length);
einfo.pattern[length] = '\0';
@@ -794,45 +793,40 @@ LineEdit(Widget w)
/* Check bounds to work on */
if (replace) {
- int i, csubst;
+ int i, j, ch;
/* Check number of required match results and remove/parse backslashes */
- memcpy(einfo.subst, rstart, einfo.slen = rend - rstart);
+ einfo.slen = rend - rstart;
einfo.sref = 0;
einfo.soff = offset;
- for (i = 0; i < einfo.slen - 1; i++) {
- if (einfo.subst[i] == '\\') {
- csubst = -1;
- switch (einfo.subst[i + 1]) {
- case '0': csubst = '\0'; break;
- case 'a': csubst = '\b'; break;
- case 'b': csubst = '\b'; break;
- case 'f': csubst = '\f'; break;
- case 'n': csubst = '\n'; break;
- case 'r': csubst = '\r'; break;
- case 't': csubst = '\t'; break;
- case 'v': csubst = '\v'; break;
- case '1': case '2': case '3':
- case '4': case '5': case '6':
- case '7': case '8': case '9':
- ++i;
- if (einfo.subst[i] - '0' > einfo.sref)
- einfo.sref = einfo.subst[i] - '0';
- break;
+ for (i = j = 0; i < einfo.slen; i++) {
+ ch = rstart[i];
+ if (ch == '\\') {
+ ++i;
+ switch (rstart[i]) {
+ case '0': ch = '\0'; break;
+ case 'a': ch = '\a'; break;
+ case 'b': ch = '\b'; break;
+ case 'f': ch = '\f'; break;
+ case 'n': ch = '\n'; break;
+ case 'r': ch = '\r'; break;
+ case 't': ch = '\t'; break;
+ case 'v': ch = '\v'; break;
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ einfo.subst[j++] = '\\';
+ if (rstart[i] - '0' > einfo.sref)
+ einfo.sref = rstart[i] - '0';
+ /* FALLTHROUGH */
default:
- csubst = einfo.subst[i + 1];
+ ch = rstart[i];
break;
}
- if (csubst >= 0) {
- memmove(einfo.subst + i, einfo.subst + i + 1,
- einfo.slen - i);
- einfo.subst[i] = csubst;
- --einfo.slen;
- ++i;
- csubst = -1;
- }
}
+ einfo.subst[j++] = ch;
}
+ einfo.slen = j;
}
else if (einfo.widget != w) {
/* Just a flag for backward search */
@@ -842,8 +836,36 @@ LineEdit(Widget w)
/* Compile pattern if required */
if (compile) {
+ int ch;
+ char *eptr, *pptr;
+
+ /* Parse backslashes */
+ pptr = einfo.subst_pattern;
+ for (eptr = einfo.pattern, ch = *eptr++; ch; ch = *eptr++) {
+ if (ch == '\\') {
+ switch (*eptr) {
+ case '0': ch = '\0'; einfo.flags |= RE_PEND; break;
+ case 'a': ch = '\a'; break;
+ case 'b': ch = '\b'; break;
+ case 'f': ch = '\f'; break;
+ case 'n': ch = '\n'; break;
+ case 'r': ch = '\r'; break;
+ case 't': ch = '\t'; break;
+ case 'v': ch = '\v'; break;
+ default: break;
+ }
+ if (ch != '\\')
+ ++eptr;
+ }
+ *pptr++ = ch;
+ }
+ *pptr = '\0';
+
refree(&einfo.regex);
- if ((ecode = recomp(&einfo.regex, einfo.pattern, einfo.flags)) != 0)
+ /* Allow nuls in search regex */
+ einfo.regex.re_endp = pptr;
+ ecode = recomp(&einfo.regex, einfo.subst_pattern, einfo.flags);
+ if (ecode)
goto print;
}
@@ -912,7 +934,7 @@ confirm_label:
}
memcpy(einfo.line, block.ptr, block.length);
length = block.length;
- for (position += length; position < to; position += length) {
+ for (position += length; position < to; position += block.length) {
XawTextSourceRead(source, position, &block, to - position);
memcpy(einfo.line + length, block.ptr, block.length);
length += block.length;
@@ -922,29 +944,39 @@ confirm_label:
/* Execute expression */
einfo.mats[0].rm_so = 0;
- einfo.mats[0].rm_eo = to - from - !(from == to || to == last);
- ecode = reexec(&einfo.regex, line,
- einfo.sref + 1, &einfo.mats[0], flags);
+ einfo.mats[0].rm_eo = to - from;
- if (replace && einfo.mats[0].rm_so == einfo.mats[0].rm_eo)
- /* Ignore empty matches */
- ecode = RE_NOMATCH;
+ /* If not last line or if it ends in a newline */
+ if (to != from) {
+ if (to < last || (to > from && line[einfo.mats[0].rm_eo - 1] == '\n'))
+ --einfo.mats[0].rm_eo;
- if (ecode == 0 && confirm &&
- (einfo.soff == O_ALL || nth == einfo.soff)) {
- einfo.end = from + einfo.mats[0].rm_eo;
- einfo.start = from + einfo.mats[0].rm_so;
- XawTextSetInsertionPoint(w, einfo.end);
- XawTextSetSelection(w, einfo.start, einfo.end);
+ ecode = reexec(&einfo.regex, line,
+ einfo.sref + 1, &einfo.mats[0], flags);
- einfo.state = SubstituteAsk;
- einfo.from = from;
- einfo.to = to;
- einfo.first = first;
- einfo.last = last;
- einfo.text_line = line;
- break;
+ if (replace && einfo.mats[0].rm_so == einfo.mats[0].rm_eo)
+ /* Ignore empty matches */
+ ecode = RE_NOMATCH;
+
+ if (ecode == 0 && confirm &&
+ (einfo.soff == O_ALL || nth == einfo.soff)) {
+ einfo.end = from + einfo.mats[0].rm_eo;
+ einfo.start = from + einfo.mats[0].rm_so;
+ XawTextSetInsertionPoint(w, einfo.end);
+ XawTextSetSelection(w, einfo.start, einfo.end);
+
+ einfo.state = SubstituteAsk;
+ einfo.from = from;
+ einfo.to = to;
+ einfo.first = first;
+ einfo.last = last;
+ einfo.text_line = line;
+ break;
+ }
}
+ else
+ /* Check bellow will update offsets */
+ ecode = RE_NOMATCH;
substitute_label:
if (ecode == 0) {
@@ -1086,6 +1118,7 @@ no_substitute_label:
else
XtSetArg(args[0], XtNstring, NULL);
XtSetValues(filenamewindow, args, 1);
+ line_edit = False;
}
return;