ed

simple ed
git clone git://git.2f30.org/ed
Log | Files | Refs | LICENSE

commit f2593570542c7916d04f30e54f685eeb92cf5b90
parent 91e4a06811bd9d9358b2154bbf060de5250dd5db
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 12 Dec 2015 11:33:55 +0100

Add basic skeleton for s command

This code only parses the input and set the variables
that are needed in the next step, go through the lines
addressed and apply the substituion.

Diffstat:
Med.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+), 0 deletions(-)

diff --git a/ed.c b/ed.c @@ -48,6 +48,9 @@ char *ocmdline; size_t cmdsiz, cmdcap; int repidx; +int gsub; +char *lhs, *rhs; + static void error(char *msg) { @@ -801,6 +804,83 @@ execsh(void) } static void +getlhs(int delim) +{ + int c; + char *s; + + back(c = input()); + if (c == delim) { + if ((s = lastre) == NULL) + error("No previous substitution"); + } else { + s = getregex(delim); + } + free(lhs); + if ((lhs = strdup(s)) == NULL) + error("out of memory"); + + compile(lhs); + if (input() != delim) + error("invalid pattern delimiter"); +} + +static void +getrhs(int delim) +{ + char *repl; + int c; + size_t n, siz, cap; + + repl = NULL; + siz = cap = 0; + while ((c = input()) != '\n' && c != EOF && c != delim) { + if (c == '\\') { + if (isdigit(c = input())) + back(c); + } + repl = addchar(c, repl, &siz, &cap); + } + back(c); + repl = addchar('\0', repl, &siz, &cap); + + if (!strcmp("%", repl)) { + free(repl); + if (!rhs) + error("no previous substitution"); + } else { + free(rhs); + rhs = repl; + } +} + +static void +subs(void) +{ + int c, delim; + + + if ((delim = input()) == '\n') { + if (!rhs || !lhs) + error("no previous substitution"); + } else { + gsub = 0; + getlhs(delim); + getrhs(delim); + + if (c == delim) { + if ((c = input()) == 'g') + gsub = 1; + else + back(c); + } else { + pflag = 'p'; + back(c); + } + } +} + +static void docmd(void) { char *s, cmd; @@ -879,6 +959,11 @@ repeat: deflines(lastln, lastln); printf("%d\n", line1); break; + case 's': + deflines(curln, curln); + subs(); + chkprint(1); + break; case 'i': if (nlines > 1) goto bad_address;