From 0801eb15f67fb69f5ce3d1fcf0911b3d38e3375e Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Fri, 26 Apr 2019 23:27:56 -0400 Subject: [PATCH] implemented substitute command --- src/lib/buf.c | 15 ++++++++++++ src/tsed.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/src/lib/buf.c b/src/lib/buf.c index 712386d..d49d70d 100644 --- a/src/lib/buf.c +++ b/src/lib/buf.c @@ -153,6 +153,21 @@ static Sel selswap(Sel sel) { return sel; } +//static void proc_lines(Buf* buf) { +// if (!buf_end(buf)) return; +// Sel sel = buf->selection; +// buf->selection.beg = buf->selection.end = 0; +// size_t bend = buf_end(buf); +// while (buf->selection.end < bend) { +// buf->selection.end = buf_byline(buf, buf->selection.end, DOWN); +// char* s = buf_gets(buf); +// printf("'%s'\n", s); +// free(s); +// buf->selection.beg = buf->selection.end; +// } +// buf->selection = sel; +//} + static void trim_whitespace(Buf* buf) { if (!TrimOnSave || !buf_end(buf)) return; Sel sel = buf->selection; diff --git a/src/tsed.c b/src/tsed.c index 457f04f..22df342 100644 --- a/src/tsed.c +++ b/src/tsed.c @@ -12,7 +12,7 @@ enum { typedef struct { int flags; - size_t capacity; + ssize_t capacity; ssize_t length; char* buffer; } LineBuf; @@ -48,16 +48,65 @@ typedef struct { typedef void (*CmdFn)(Cmd* cmd, LineBuf* buf); +static void lbputc(LineBuf* lbuf, int c) { + if ((lbuf->length + 2u) >= lbuf->capacity) { + lbuf->capacity += 2u; + lbuf->buffer = realloc(lbuf->buffer, lbuf->capacity); + } + lbuf->buffer[lbuf->length++] = c; + lbuf->buffer[lbuf->length] = '\0'; +} + +static void lbputsn(LineBuf* lbuf, char* s, ssize_t l) { +#if 1 + for (ssize_t i = 0; i < l; i++) + lbputc(lbuf, *(s+i)); +#else + if ((lbuf->length + l + 1) >= lbuf->capacity) { + lbuf->capacity += (l + 1); + lbuf->buffer = realloc(lbuf->buffer, lbuf->capacity); + } + memcpy((lbuf->buffer + lbuf->length), s, l); + lbuf->length += l; + lbuf->buffer[lbuf->length] = '\0'; +#endif +} + static void cmd_d(Cmd* cmd, LineBuf* lbuf) { (void)cmd; lbuf->flags |= LB_DELETE; } static void cmd_s(Cmd* cmd, LineBuf* lbuf) { - regmatch_t match[10] = {0}; - if (!regexec(cmd->regex, lbuf->buffer, 10, match, 0)) { -// lbuf->flags |= LB_DELETE; - } + regmatch_t match[10]; + LineBuf out = {0}; + char* pos = lbuf->buffer; + do { + memset(match, 0, sizeof(match)); + if (!regexec(cmd->regex, pos, 10, match, 0)) { + lbputsn(&out, pos, match[0].rm_so); + for (char* rs = cmd->text; *rs; rs++) { + if (*rs == '\\') { + rs++; + if (isdigit(*rs)) { + int i = *rs - '0'; + lbputsn(&out, (pos + match[i].rm_so), (match[i].rm_eo - match[i].rm_so)); + } else { + lbputc(&out, *rs); + } + } else { + lbputc(&out, *rs); + } + } + pos += match[0].rm_eo; + } else { + lbputsn(&out, pos, (lbuf->length - (pos - lbuf->buffer) - 1)); + break; + } + } while (*pos && (cmd->flags & SUB_GLOBAL)); + lbuf->length = 0; + lbputsn(lbuf, out.buffer, out.length); + free(out.buffer); } static const CmdFn Commands[] = { @@ -77,7 +126,7 @@ static int match_addr(Prog* prog, Addr* addr, LineBuf* lbuf) { } static char* rdline(LineBuf* buf, FILE* file) { - buf->length = getline(&(buf->buffer), &(buf->capacity), file); + buf->length = getline(&(buf->buffer), (size_t*)&(buf->capacity), file); buf->flags = 0; if (buf->length <= 0) { free(buf->buffer); @@ -232,5 +281,11 @@ int main(int argc, char** argv) { } prog_free(prog); +// (void)argc, (void)argv, (void)rdline; +// LineBuf buf = {0}; +// lbputsn(&buf, "foo", 3); +// lbputsn(&buf, "bar", 3); +// printf("%s\n", buf.buffer); + return 0; } -- 2.52.0