]> git.mdlowis.com Git - projs/tide.git/commitdiff
implemented substitute command
authorMichael D. Lowis <mike@mdlowis.com>
Sat, 27 Apr 2019 03:27:56 +0000 (23:27 -0400)
committerMichael D. Lowis <mike@mdlowis.com>
Sat, 27 Apr 2019 03:27:56 +0000 (23:27 -0400)
src/lib/buf.c
src/tsed.c

index 712386dad72d7a0ba6223924236e25866f808054..d49d70d4f7b0b9210b3accefe56627f7d849541f 100644 (file)
@@ -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;
index 457f04ff59b0050a9d68e007c5ca177de7c3ceb9..22df342cbcce95b4d029008920014ddc06c56ac8 100644 (file)
@@ -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;
 }