aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMassimiliano Ghilardi <massimiliano.ghilardi@gmail.com>2023-01-12 20:06:31 (GMT)
committerMassimiliano Ghilardi <massimiliano.ghilardi@gmail.com>2023-01-12 20:06:31 (GMT)
commitcade2c07eeadbd230b9c64607750813415b8231e (patch)
tree1d5eae0ae687b9af42afd543db62b6082957ce19
parent57cc8e95ac7f96ff6eae17b46edc60b01f2d0e0a (diff)
downloadpowwow-cade2c07eeadbd230b9c64607750813415b8231e.zip
powwow-cade2c07eeadbd230b9c64607750813415b8231e.tar.gz
powwow-cade2c07eeadbd230b9c64607750813415b8231e.tar.bz2
implement command #substitute [string[=[text]]]
-rw-r--r--src/cmd.c20
-rw-r--r--src/cmd2.c120
-rw-r--r--src/cmd2.h4
-rw-r--r--src/defines.h19
-rw-r--r--src/edit.c3
-rw-r--r--src/list.c76
-rw-r--r--src/list.h6
-rw-r--r--src/main.c5
-rw-r--r--src/main.h1
-rw-r--r--src/utils.c157
-rw-r--r--src/utils.h5
11 files changed, 349 insertions, 67 deletions
diff --git a/src/cmd.c b/src/cmd.c
index f11dd53..847fbdc 100644
--- a/src/cmd.c
+++ b/src/cmd.c
@@ -62,7 +62,7 @@ static void F(help), F(shell), F(action), F(add),
F(rawsend), F(rawprint), F(rebind), F(rebindall), F(rebindALL),
F(record), F(request), F(reset), F(retrace),
F(save), F(send), F(setvar), F(snoop), F(spawn), F(stop),
- F(time), F(var), F(ver), F(while), F(write),
+ F(substitute), F(time), F(var), F(ver), F(while), F(write),
F(eval), F(zap), F(module), F(group), F(speedwalk), F(groupdelim);
#ifdef BUG_TELNET
@@ -227,6 +227,8 @@ cmdstruct default_commands[] =
"connect-id command\ttalk with a shell command"),
C("speedwalk", cmd_speedwalk,
"[speedwalk sequence]\texecute a speedwalk sequence explicitly"),
+ C("substitute", cmd_substitute,
+ "[string[=[text]]]\tdelete/list/define substitutions"),
C("stop", cmd_stop,
"\t\t\t\tremove all delayed commands from active list"),
C("time", cmd_time,
@@ -1281,6 +1283,12 @@ static void cmd_reset(char *arg)
if (!all)
return;
}
+ if (all || !strcmp(arg, "substitute")) {
+ while (substitutions)
+ delete_substnode(&substitutions);
+ if (!all)
+ return;
+ }
if (all || !strcmp(arg, "var")) {
int n;
varnode **first;
@@ -1335,6 +1343,14 @@ static void cmd_stop(char *arg)
}
}
+static void cmd_substitute(char *arg)
+{
+ if (!*arg)
+ show_substitutions();
+ else
+ parse_substitute(arg);
+}
+
static void cmd_time(char *arg)
{
struct tm *s;
@@ -2709,5 +2725,3 @@ static void cmd_put(char *arg)
put_history(arg);
ptrdel(pbuf);
}
-
-
diff --git a/src/cmd2.c b/src/cmd2.c
index dbd264a..1503f88 100644
--- a/src/cmd2.c
+++ b/src/cmd2.c
@@ -879,8 +879,8 @@ void show_marks(void)
(markers && !markers->next) ? " is" : "s are",
markers ? ':' : '.');
for (p = markers; p; p = p->next)
- tty_printf("#mark %s%s=%s\n", p->mbeg ? "^" : "",
- p->pattern, attr_name(p->attrcode));
+ tty_printf("#mark %s%s=%s\n", p->b.mbeg ? "^" : "",
+ p->b.pattern, attr_name(p->attrcode));
}
@@ -894,7 +894,7 @@ void parse_mark(char *str)
char mbeg = 0;
if (*str == '=') {
- PRINTF("#marker must be non-null.\n");
+ PRINTF("#marker must be non-empty.\n");
return;
}
p = first_regular(str, '=');
@@ -906,10 +906,10 @@ void parse_mark(char *str)
if ((n = *np)) {
ptr pbuf = (ptr)0;
char *name;
- pbuf = ptrmescape(pbuf, n->pattern, strlen(n->pattern), 0);
+ pbuf = ptrmescape(pbuf, n->b.pattern, strlen(n->b.pattern), 0);
if (MEM_ERROR) { ptrdel(pbuf); return; }
name = attr_name(n->attrcode);
- sprintf(inserted_next, "#mark %s%.*s=%.*s", n->mbeg ? "^" : "",
+ sprintf(inserted_next, "#mark %s%.*s=%.*s", n->b.mbeg ? "^" : "",
BUFSIZE-(int)strlen(name)-9, pbuf ? ptrdata(pbuf) : "",
BUFSIZE-9, name);
ptrdel(pbuf);
@@ -949,8 +949,8 @@ void parse_mark(char *str)
} else if (!*p)
if ((n = *np)) {
if (opt_info) {
- PRINTF("#deleting mark: %s%s=%s\n", n->mbeg ? "^" : "",
- n->pattern, attr_name(n->attrcode));
+ PRINTF("#deleting mark: %s%s=%s\n", n->b.mbeg ? "^" : "",
+ n->b.pattern, attr_name(n->attrcode));
}
delete_marknode(np);
} else {
@@ -976,6 +976,111 @@ void parse_mark(char *str)
}
}
+
+/*
+ * show defined substitutions
+ */
+void show_substitutions(void)
+{
+ substnode *p;
+ PRINTF("#%s substitution%s defined%c\n", substitutions ? "the following" : "no",
+ (substitutions && !substitutions->next) ? " is" : "s are",
+ substitutions ? ':' : '.');
+ for (p = substitutions; p; p = p->next)
+ tty_printf("#substitute %s%s=%s\n", p->b.mbeg ? "^" : "",
+ p->b.pattern, p->replacement);
+}
+
+
+/*
+ * parse arguments to the #mark command
+ */
+void parse_substitute(char *str)
+{
+ char *p;
+ substnode **np, *n;
+ char mbeg = 0;
+
+ if (*str == '=') {
+ PRINTF("#substitute must be non-empty.\n");
+ return;
+ }
+ p = first_regular(str, '=');
+ if (!*p) {
+ if (*str == '^')
+ mbeg = 1, str++;
+ unescape(str);
+ np = lookup_subst(str, mbeg);
+ if ((n = *np)) {
+ char *replacement = n->replacement;
+ ptr pbuf = ptrmescape(pbuf, n->b.pattern, strlen(n->b.pattern), 0);
+ if (MEM_ERROR) { ptrdel(pbuf); return; }
+ sprintf(inserted_next, "#substitute %s%.*s=%.*s", n->b.mbeg ? "^" : "",
+ BUFSIZE-(int)strlen(replacement)-14, pbuf ? ptrdata(pbuf) : "",
+ BUFSIZE-14, replacement);
+ ptrdel(pbuf);
+ } else {
+ PRINTF("#unknown substitution, cannot show: \"%s\"\n", str);
+ }
+
+ } else {
+ char pattern[BUFSIZE], *p2, *replacement;
+ int wild = 0;
+
+ *(p++) = '\0';
+ if (*str == '^')
+ mbeg = 1, str++;
+ my_strncpy(pattern, str, BUFSIZE-1);
+ unescape(pattern);
+ p2 = pattern;
+ while (*p2) {
+ if (ISMARKWILDCARD(*p2)) {
+ wild = 1;
+ if (ISMARKWILDCARD(*(p2 + 1))) {
+ error = SYNTAX_ERROR;
+ PRINTF("#error: two wildcards (& or $) may not be next to eachother\n");
+ return;
+ }
+ }
+ p2++;
+ }
+
+ np = lookup_subst(pattern, mbeg);
+ replacement = p;
+ if (!*p)
+ if ((n = *np)) {
+ if (opt_info) {
+ PRINTF("#deleting substitution: %s%s=%s\n", n->b.mbeg ? "^" : "",
+ n->b.pattern, n->replacement);
+ }
+ delete_substnode(np);
+ } else {
+ PRINTF("#unknown substitution, cannot delete: \"%s%s\"\n",
+ mbeg ? "^" : "", pattern);
+ }
+ else {
+ if ((n = *np)) {
+ if (!(replacement = my_strdup(replacement))) {
+ return;
+ }
+ if (n->replacement) { free(n->replacement); }
+ n->replacement = replacement;
+ if (opt_info) {
+ PRINTF("#changed");
+ }
+ } else {
+ add_substnode(pattern, replacement, mbeg, wild);
+ if (opt_info) {
+ PRINTF("#new");
+ }
+ }
+ if (opt_info)
+ tty_printf(" substitution: %s%s=%s\n", mbeg ? "^" : "",
+ pattern, replacement);
+ }
+ }
+}
+
/*
* turn ASCII description of a sequence
* into raw escape sequence
@@ -1673,4 +1778,3 @@ void exe_history(int count)
parse_user_input(buf, 0);
}
}
-
diff --git a/src/cmd2.h b/src/cmd2.h
index 96cb067..7e9e1fe 100644
--- a/src/cmd2.h
+++ b/src/cmd2.h
@@ -14,6 +14,9 @@ char *attr_name(int attrcode);
void show_marks(void);
void parse_mark(char *str);
+void show_substitutions(void);
+void parse_substitute(char *str);
+
char *seq_name(char *seq, int len);
void show_binds(char edit);
void parse_bind(char *arg);
@@ -29,4 +32,3 @@ void new_delaynode(char *name, char *command, long millisec);
void show_history(int count);
void exe_history(int count);
-
diff --git a/src/defines.h b/src/defines.h
index 1e273e1..87687ef 100644
--- a/src/defines.h
+++ b/src/defines.h
@@ -215,15 +215,25 @@ typedef struct aliasnode {
int active;
} aliasnode;
-typedef struct marknode {
- struct marknode *next;
+typedef struct basenode {
char *pattern;
- int attrcode;
- char *start, *end;
+ char *start, *end; // temporary data: start/end of current line match
char mbeg;
char wild;
+} basenode;
+
+typedef struct marknode {
+ struct marknode *next;
+ basenode b;
+ int attrcode;
} marknode;
+typedef struct substnode {
+ struct substnode *next;
+ basenode b;
+ char *replacement;
+} substnode;
+
typedef struct triggernode {
struct triggernode *next;
char *command, *label;
@@ -303,4 +313,3 @@ typedef struct editsess {
} editsess;
#endif /* _DEFINES_H_ */
-
diff --git a/src/edit.c b/src/edit.c
index bcfab21..d42d8bb 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -133,7 +133,7 @@ void draw_prompt(void)
char *esc, *pstr;
int e = error;
error = 0;
- marked_prompt = ptraddmarks(marked_prompt, prompt->str);
+ marked_prompt = ptraddsubst_and_marks(marked_prompt, prompt->str);
if (MEM_ERROR) { promptzero(); errmsg("malloc(prompt)"); return; }
/* if prompt ends in unterminated escape code, do not print
@@ -958,4 +958,3 @@ void edit_bootstrap(void)
{
default_completions();
}
-
diff --git a/src/list.c b/src/list.c
index 2652bda..3e7471b 100644
--- a/src/list.c
+++ b/src/list.c
@@ -23,6 +23,7 @@
#include "feature/regex.h"
#include "utils.h"
#include "cmd2.h"
+#include "list.h"
#include "tty.h"
#include "eval.h"
@@ -206,12 +207,13 @@ void add_marknode(char *pattern, int attrcode, char mbeg, char wild)
errmsg("malloc");
return;
}
- new->pattern = my_strdup(pattern);
+ new->next = NULL;
+ new->b.pattern = my_strdup(pattern);
+ new->b.start = new->b.end = NULL;
+ new->b.mbeg = mbeg;
+ new->b.wild = wild;
new->attrcode = attrcode;
- new->start = new->end = NULL;
- new->mbeg = mbeg;
- new->wild = wild;
- if (!new->pattern) {
+ if (!new->b.pattern) {
errmsg("malloc");
free(new);
return;
@@ -226,6 +228,39 @@ void add_marknode(char *pattern, int attrcode, char mbeg, char wild)
#endif
}
+
+/*
+ * add a node to the substitution list
+ */
+void add_substnode(char *pattern, char *replacement, char mbeg, char wild)
+{
+ substnode **p, *new = (substnode*)malloc(sizeof(substnode));
+ int i;
+ if (!new) {
+ errmsg("malloc");
+ return;
+ }
+ new->next = NULL;
+ new->b.pattern = my_strdup(pattern);
+ new->b.start = new->b.end = NULL;
+ new->b.mbeg = mbeg;
+ new->b.wild = wild;
+ new->replacement = my_strdup(replacement);
+ if (!new->b.pattern || (replacement && !new->replacement)) {
+ errmsg("malloc");
+ delete_substnode(&new);
+ return;
+ }
+#ifdef DO_SORT
+ add_node((defnode*)new, (defnode**)&substitutions, ascii_sort);
+#else
+ for (p=&substitutions, i=1; *p && (a_nice==0 || i<a_nice); p = &(*p)->next, i++)
+ ;
+ new->next = *p;
+ *p = new;
+#endif
+}
+
/*
* add a node to the action list
*/
@@ -487,13 +522,25 @@ actionnode **lookup_prompt(char *label)
}
/*
- * look up an marker node by pattern:
+ * look up a marker node by pattern:
* return pointer to pointer to node or a pointer to NULL if nothing found
*/
marknode **lookup_marker(char *pattern, char mbeg)
{
marknode **p = &markers;
- while (*p && (mbeg != (*p)->mbeg || strcmp(pattern, (*p)->pattern)))
+ while (*p && (mbeg != (*p)->b.mbeg || strcmp(pattern, (*p)->b.pattern)))
+ p = &(*p)->next;
+ return p;
+}
+
+/*
+ * look up a substitution node by pattern:
+ * return pointer to pointer to node or a pointer to NULL if nothing found
+ */
+substnode **lookup_subst(char *pattern, char mbeg)
+{
+ substnode **p = &substitutions;
+ while (*p && (mbeg != (*p)->b.mbeg || strcmp(pattern, (*p)->b.pattern)))
p = &(*p)->next;
return p;
}
@@ -505,7 +552,6 @@ marknode **lookup_marker(char *pattern, char mbeg)
keynode **lookup_key(char *name)
{
keynode **p = &keydefs;
-
while (*p && strcmp(name, (*p)->name))
p = &(*p)->next;
return p;
@@ -596,7 +642,19 @@ void delete_promptnode(promptnode **base)
void delete_marknode(marknode **base)
{
marknode *p = *base;
- if (p->pattern) free(p->pattern);
+ if (p->b.pattern) free(p->b.pattern);
+ *base = p->next;
+ free((void*)p);
+}
+
+/*
+ * delete a substnode, given a pointer to its precessor's pointer
+ */
+void delete_substnode(substnode **base)
+{
+ substnode *p = *base;
+ if (p->b.pattern) free(p->b.pattern);
+ if (p->replacement) free(p->replacement);
*base = p->next;
free((void*)p);
}
diff --git a/src/list.h b/src/list.h
index c336049..c57167e 100644
--- a/src/list.h
+++ b/src/list.h
@@ -13,7 +13,7 @@ int rev_ascii_sort(defnode *node1, defnode *node2);
int time_sort(defnode *node1, defnode *node2);
int rev_time_sort(defnode *node1, defnode *node2);
-int hash(char *name);
+int hash(char *name, int optlen);
void add_node(defnode *newnode, defnode **base, function_sort sort);
void reverse_sortedlist(sortednode **base);
@@ -23,6 +23,7 @@ void add_actionnode(char *pattern, char *command, char *label, int active, int t
void add_promptnode(char *pattern, char *command, char *label, int active, int type, void *qregexp);
void add_marknode(char *pattern, int attrcode, char mbeg, char wild);
void add_keynode(char *name, char *sequence, int seqlen, function_str funct, char *call_data);
+void add_substnode(char *pattern, char *replacement, char mbeg, char wild);
delaynode *add_delaynode(char *name, char *command, vtime *when, int is_dead);
varnode *add_varnode(char *name, int type);
@@ -31,6 +32,7 @@ actionnode **lookup_action(char *label);
actionnode **lookup_prompt(char *label);
actionnode **lookup_action_pattern(char *pattern);
marknode **lookup_marker(char *pattern, char mbeg);
+substnode **lookup_subst(char *pattern, char mbeg);
keynode **lookup_key(char *name);
delaynode **lookup_delay(char *name, int is_dead);
varnode **lookup_varnode(char *name, int type);
@@ -41,7 +43,7 @@ void delete_promptnode(promptnode **base);
void delete_marknode(marknode **base);
void delete_keynode(keynode **base);
void delete_delaynode(delaynode **base);
+void delete_substnode(substnode **base);
void delete_varnode(varnode **base, int type);
#endif /* _LIST_H_ */
-
diff --git a/src/main.c b/src/main.c
index 3c7fe9b..fb81415 100644
--- a/src/main.c
+++ b/src/main.c
@@ -13,7 +13,7 @@
*
* Initially inspired to the Tintin client by Peter Unold,
* Powwow contains no Tintin code.
- * The original program Cancan, written by Mattias Engdegård (Yorick)
+ * The original program Cancan, written by Mattias Engdeg�rd (Yorick)
* (f91-men@nada.kth.se) 1992-94,
* was greatly improved upon by Vivriel, Thuzzle and Ilie and then
* transformed from Cancan into Powwow by Cosmos who worked
@@ -158,7 +158,8 @@ aliasnode *sortedaliases; /* head of (ASCII) sorted alias list */
actionnode *actions; /* head of action list */
promptnode *prompts; /* head of prompt list */
marknode *markers; /* head of mark list */
-int a_nice = 0; /* default priority of new actions/marks */
+substnode *substitutions; /* head of substitution list */
+int a_nice = 0; /* default priority of new actions/marks/substitutions */
keynode *keydefs; /* head of key binding list */
delaynode *delays; /* head of delayed commands list */
delaynode *dead_delays; /* head of dead-delayed commands list */
diff --git a/src/main.h b/src/main.h
index e76f7cb..3daafc3 100644
--- a/src/main.h
+++ b/src/main.h
@@ -63,6 +63,7 @@ extern aliasnode *sortedaliases;
extern actionnode *actions;
extern promptnode *prompts;
extern marknode *markers;
+extern substnode *substitutions;
extern int a_nice;
extern keynode *keydefs;
extern delaynode *delays;
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++) {
diff --git a/src/utils.h b/src/utils.h
index f5b8704..833b0ba 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -13,8 +13,8 @@ int memunescape(char *p, int lenp);
ptr ptrescape(ptr dst, ptr src, int append);
ptr ptrmescape(ptr dst, char *src, int srclen, int append);
-ptr ptraddmarks(ptr dst, ptr line);
-ptr ptrmaddmarks(ptr dst, char *line, int len);
+ptr ptraddsubst_and_marks(ptr dst, ptr line);
+ptr ptrmaddsubst_and_marks(ptr dst, char *line, int len);
void put_marks(char *dst, char *line);
void smart_print(char *line, char newline);
@@ -45,4 +45,3 @@ void movie_write(char *str, int newline);
void update_now(void);
#endif /* _UTILS_H_ */
-