aboutsummaryrefslogtreecommitdiffstats
path: root/src/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.c')
-rw-r--r--src/utils.c157
1 files changed, 125 insertions, 32 deletions
diff --git a/src/utils.c b/src/utils.c
index f6582ef..0c3be5d 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -334,24 +334,24 @@ void escape_specials(char *dst, char *src)
* if 1, start and end contain the match bounds
* if 0, start and end are undefined on return
*/
-static int match_mark(marknode *mp, char *src)
+static int match_mark_or_subst(basenode *bp, char *src)
{
- char *pat = mp->pattern;
+ char *pat = bp->pattern;
char *npat=0, *npat2=0, *nsrc=0, *prm=0, *endprm=0, *tmp, c;
static char mpat[BUFSIZE];
- int mbeg = mp->mbeg, mword = 0, p;
+ int mbeg = bp->mbeg, mword = 0, p;
/* shortcut for #marks without wildcards */
- if (!mp->wild) {
+ if (!bp->wild) {
if ((nsrc = strstr(src, pat))) {
- mp->start = nsrc;
- mp->end = nsrc + strlen(pat);
+ bp->start = nsrc;
+ bp->end = nsrc + strlen(pat);
return 1;
}
return 0;
}
- mp->start = NULL;
+ bp->start = NULL;
if (ISMARKWILDCARD(*pat))
mbeg = - mbeg - 1; /* pattern starts with '&' or '$' */
@@ -363,8 +363,8 @@ static int match_mark(marknode *mp, char *src)
prm = src;
if (c == '$')
mword = 1;
- else if (!mp->start)
- mp->start = src;
+ else if (!bp->start)
+ bp->start = src;
++pat;
}
@@ -389,17 +389,17 @@ static int match_mark(marknode *mp, char *src)
mbeg = 0; /* reset mbeg to stop further start match */
}
endprm = nsrc;
- if (!mp->start) {
+ if (!bp->start) {
if (prm)
- mp->start = src;
+ bp->start = src;
else
- mp->start = nsrc;
+ bp->start = nsrc;
}
- mp->end = nsrc + strlen(mpat);
+ bp->end = nsrc + strlen(mpat);
} else if (prm) /* end of pattern space */
- mp->end = endprm = prm + strlen(prm);
+ bp->end = endprm = prm + strlen(prm);
else
- mp->end = src;
+ bp->end = src;
/* post-processing of param */
@@ -417,11 +417,11 @@ static int match_mark(marknode *mp, char *src)
else
p = -1;
}
- mp->start = prm += p + 1;
+ bp->start = prm += p + 1;
} else if (!*pat) {
/* '$' at end of pattern, take first word */
if ((tmp = memchrs(prm, strlen(prm), DELIM, DELIM_LEN)))
- mp->end = endprm = tmp;
+ bp->end = endprm = tmp;
} else {
/* match only if param is single-worded */
if (memchrs(prm, endprm - prm, DELIM, DELIM_LEN))
@@ -441,7 +441,7 @@ static int match_mark(marknode *mp, char *src)
/*
* add marks to line. write in dst.
*/
-ptr ptrmaddmarks(ptr dst, char *line, int len)
+static ptr ptrmaddmarks(ptr dst, char *line, int len)
{
marknode *mp, *mfirst;
char begin[CAPLEN], end[CAPLEN], *lineend = line + len;
@@ -453,19 +453,19 @@ ptr ptrmaddmarks(ptr dst, char *line, int len)
return dst;
for (mp = markers; mp; mp = mp->next)
- mp->start = NULL;
+ mp->b.start = NULL;
do {
mfirst = NULL;
for (mp = markers; mp; mp = mp->next) {
- if (mp->start && mp->start >= line)
+ if (mp->b.start && mp->b.start >= line)
matched = 1;
else {
- if (!(matched = (!mp->mbeg || start) && match_mark(mp, line)))
- mp->start = lineend;
+ if (!(matched = (!mp->b.mbeg || start) && match_mark_or_subst(&mp->b, line)))
+ mp->b.start = lineend;
}
- if (matched && mp->start < lineend &&
- (!mfirst || mp->start < mfirst->start))
+ if (matched && mp->b.start < lineend &&
+ (!mfirst || mp->b.start < mfirst->b.start))
mfirst = mp;
}
@@ -473,7 +473,7 @@ ptr ptrmaddmarks(ptr dst, char *line, int len)
start = 0;
attr_string(mfirst->attrcode, begin, end);
- dst = ptrmcat(dst, line, matchlen = mfirst->start - line);
+ dst = ptrmcat(dst, line, matchlen = mfirst->b.start - line);
if (MEM_ERROR) break;
line += matchlen;
len -= matchlen;
@@ -481,7 +481,7 @@ ptr ptrmaddmarks(ptr dst, char *line, int len)
dst = ptrmcat(dst, begin, strlen(begin));
if (MEM_ERROR) break;
- dst = ptrmcat(dst, line, matchlen = mfirst->end - mfirst->start);
+ dst = ptrmcat(dst, line, matchlen = mfirst->b.end - mfirst->b.start);
if (MEM_ERROR) break;
line += matchlen;
len -= matchlen;
@@ -497,10 +497,93 @@ ptr ptrmaddmarks(ptr dst, char *line, int len)
return dst;
}
-ptr ptraddmarks(ptr dst, ptr line)
+/*
+ * add substitutions to line. write in dst.
+ */
+static ptr ptrmaddsubst(ptr dst, char *line, int len)
+{
+ substnode *sp, *sfirst;
+ char *lineend = line + len;
+ int start = 1, matchlen, matched = 0;
+
+ ptrzero(dst);
+
+ if (!line || len <= 0)
+ return dst;
+
+ for (sp = substitutions; sp; sp = sp->next)
+ sp->b.start = NULL;
+
+ do {
+ sfirst = NULL;
+ for (sp = substitutions; sp; sp = sp->next) {
+ if (sp->b.start && sp->b.start >= line)
+ matched = 1;
+ else {
+ if (!(matched = (!sp->b.mbeg || start) && match_mark_or_subst(&sp->b, line)))
+ sp->b.start = lineend;
+ }
+ if (matched && sp->b.start < lineend &&
+ (!sfirst || sp->b.start < sfirst->b.start))
+ sfirst = sp;
+ }
+
+ if (sfirst) {
+ start = 0;
+
+ dst = ptrmcat(dst, line, matchlen = sfirst->b.start - line);
+ if (MEM_ERROR) break;
+ line += matchlen;
+ len -= matchlen;
+
+ dst = ptrmcat(dst, sfirst->replacement, strlen(sfirst->replacement));
+ if (MEM_ERROR) break;
+ matchlen = sfirst->b.end - sfirst->b.start;
+ line += matchlen;
+ len -= matchlen;
+ }
+ } while (sfirst);
+
+ if (!MEM_ERROR)
+ dst = ptrmcat(dst, line, len);
+
+ return dst;
+}
+
+
+/*
+ * add substitutions and markers to line. write in dst.
+ */
+ptr ptrmaddsubst_and_marks(ptr dst, char *line, int len)
+{
+ static ptr ptrbuf = NULL;
+ if (!substitutions) {
+ return ptrmaddmarks(dst, line, len);
+ } else if (!markers) {
+ return ptrmaddsubst(dst, line, len);
+ }
+ if (!ptrbuf) {
+ ptrbuf = ptrnew(PARAMLEN);
+ if (!ptrbuf) {
+ goto fail;
+ }
+ }
+ ptrbuf = ptrmaddsubst(ptrbuf, line, len);
+ if (ptrbuf) {
+ dst = ptrmaddmarks(dst, ptrdata(ptrbuf), ptrlen(ptrbuf));
+ }
+fail:
+ if (MEM_ERROR) {
+ print_error(error);
+ ptrzero(dst);
+ }
+ return dst;
+}
+
+ptr ptraddsubst_and_marks(ptr dst, ptr line)
{
if (line)
- return ptrmaddmarks(dst, ptrdata(line), ptrlen(line));
+ return ptrmaddsubst_and_marks(dst, ptrdata(line), ptrlen(line));
ptrzero(dst);
return dst;
}
@@ -594,7 +677,7 @@ static void wrap_print(char *s)
}
/*
- * add marks to line and print.
+ * add substitutions and marks to line and print.
* if newline, also print a final \n
*/
void smart_print(char *line, char newline)
@@ -607,7 +690,7 @@ void smart_print(char *line, char newline)
ptrbuf = ptrnew(PARAMLEN);
if (MEM_ERROR) break;
}
- ptrbuf = ptrmaddmarks(ptrbuf, line, strlen(line));
+ ptrbuf = ptrmaddsubst_and_marks(ptrbuf, line, strlen(line));
if (MEM_ERROR || !ptrbuf) break;
buf = ptrdata(ptrbuf);
@@ -943,6 +1026,8 @@ int read_settings(void)
delete_marknode(&markers);
while (keydefs)
delete_keynode(&keydefs);
+ while (substitutions)
+ delete_substnode(&substitutions);
for (n = 0; n < MAX_HASH; n++) {
while (named_vars[0][n])
delete_varnode(&named_vars[0][n], 0);
@@ -1059,6 +1144,7 @@ int save_settings(void)
actionnode *acp;
promptnode *ptp;
marknode *mp;
+ substnode *sp;
keynode *kp;
varnode *vp;
ptr pp = (ptr)0;
@@ -1150,11 +1236,18 @@ int save_settings(void)
}
for (mp = markers; mp && failed > 0; mp = mp->next) {
- pp = ptrmescape(pp, mp->pattern, strlen(mp->pattern), 0);
+ pp = ptrmescape(pp, mp->b.pattern, strlen(mp->b.pattern), 0);
if (MEM_ERROR) { failed = -1; break; }
- failed = fprintf(f, "#mark %s%s=%s\n", mp->mbeg ? "^" : "",
+ failed = fprintf(f, "#mark %s%s=%s\n", mp->b.mbeg ? "^" : "",
ptrdata(pp), attr_name(mp->attrcode));
}
+
+ for (sp = substitutions; sp && failed > 0; sp = sp->next) {
+ pp = ptrmescape(pp, sp->b.pattern, strlen(sp->b.pattern), 0);
+ if (MEM_ERROR) { failed = -1; break; }
+ failed = fprintf(f, "#substitute %s%s=%s\n", sp->b.mbeg ? "^" : "",
+ ptrdata(pp), sp->replacement);
+ }
/* save value of global variables */
for (flag = 0, i=0; i<NUMVAR && failed > 0; i++) {