vis
a vi-like editor based on Plan 9's structural regular expressions
git clone https://9o.is/git/vis.git
buffer-fuzzer.c
(2246B)
1 #include <stddef.h>
2 #include <stdbool.h>
3 #include <string.h>
4 #include <errno.h>
5 #include <stdio.h>
6 #include <unistd.h>
7 #include "fuzzer.h"
8 #include "buffer.h"
9 #include "util.h"
10
11 #ifndef BUFSIZ
12 #define BUFSIZ 1024
13 #endif
14
15 typedef enum CmdStatus (*Cmd)(Buffer *buf, const char *cmd);
16
17 static enum CmdStatus cmd_insert(Buffer *buf, const char *cmd) {
18 char data[BUFSIZ];
19 size_t pos;
20 if (sscanf(cmd, "%zu %s\n", &pos, data) != 2)
21 return CMD_ERR;
22 return buffer_insert0(buf, pos, data);
23 }
24
25 static enum CmdStatus cmd_set(Buffer *buf, const char *cmd) {
26 char data[BUFSIZ];
27 if (sscanf(cmd, "%s\n", data) != 1)
28 return CMD_ERR;
29 return buffer_put0(buf, data);
30 }
31
32 static enum CmdStatus cmd_delete(Buffer *buf, const char *cmd) {
33 size_t pos, len;
34 if (sscanf(cmd, "%zu %zu", &pos, &len) != 2)
35 return CMD_ERR;
36 return buffer_remove(buf, pos, len);
37 }
38
39 static enum CmdStatus cmd_clear(Buffer *buf, const char *cmd) {
40 buffer_clear(buf);
41 return CMD_OK;
42 }
43
44 static enum CmdStatus cmd_size(Buffer *buf, const char *cmd) {
45 printf("%zu bytes\n", buffer_length(buf));
46 return CMD_OK;
47 }
48
49 static enum CmdStatus cmd_capacity(Buffer *buf, const char *cmd) {
50 printf("%zu bytes\n", buffer_capacity(buf));
51 return CMD_OK;
52 }
53
54 static enum CmdStatus cmd_print(Buffer *buf, const char *cmd) {
55 size_t len = buffer_length(buf);
56 const char *data = buffer_content(buf);
57 if (data && fwrite(data, len, 1, stdout) != 1)
58 return CMD_ERR;
59 if (data)
60 puts("");
61 return CMD_OK;
62 }
63
64 static enum CmdStatus cmd_quit(Buffer *buf, const char *cmd) {
65 return CMD_QUIT;
66 }
67
68 static Cmd commands[] = {
69 ['?'] = cmd_capacity,
70 ['='] = cmd_set,
71 ['#'] = cmd_size,
72 ['c'] = cmd_clear,
73 ['d'] = cmd_delete,
74 ['i'] = cmd_insert,
75 ['p'] = cmd_print,
76 ['q'] = cmd_quit,
77 };
78
79 int main(int argc, char *argv[]) {
80 char line[BUFSIZ];
81 Buffer buf = {0};
82
83 for (;;) {
84 printf("> ");
85 if (!fgets(line, sizeof(line), stdin))
86 break;
87 if (!isatty(0))
88 printf("%s", line);
89 if (line[0] == '\n')
90 continue;
91 size_t idx = line[0];
92 if (idx < LENGTH(commands) && commands[idx]) {
93 enum CmdStatus ret = commands[idx](&buf, line+1);
94 printf("%s", cmd_status_msg[ret]);
95 if (ret == CMD_QUIT)
96 break;
97 } else {
98 puts("Invalid command");
99 }
100 }
101
102 buffer_release(&buf);
103
104 return 0;
105 }