aboutsummaryrefslogtreecommitdiff
path: root/core/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/read.c')
-rw-r--r--core/read.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/core/read.c b/core/read.c
new file mode 100644
index 0000000..82b74be
--- /dev/null
+++ b/core/read.c
@@ -0,0 +1,96 @@
+#include "../lib/io/io.h"
+#include "../lib/arg/arg.h"
+#include "../lib/list/list.h"
+
+#define BUF_SIZE 1024
+
+void mode_all(int fd);
+void mode_singleline(int fd);
+
+enum Modes {
+ MODE_ALL,
+ MODE_SINGLELINE,
+ MODE_SIZE
+} mode;
+
+char buf[BUF_SIZE] = "";
+list_t *files;
+void(*mode_funcs[MODE_SIZE])(int fd) = {
+ mode_all,
+ mode_singleline
+};
+
+void add_file(const char *path)
+{
+ list_append(files, (void*)path);
+}
+
+
+void add_stdin()
+{
+ list_append(files, 0);
+}
+
+
+void set_singleline_mode()
+{
+ mode = MODE_SINGLELINE;
+}
+
+
+void mode_all(int fd)
+{
+ u64 rs;
+ while ((rs = read(fd, buf, BUF_SIZE - 1))) {
+ buf[rs] = 0;
+ wstd(buf);
+ }
+}
+
+
+void mode_singleline(int fd)
+{
+ u64 rs;
+ u64 has_newline_char = 0;
+ char *p;
+ while (!has_newline_char) {
+ rs = read(fd, buf, BUF_SIZE - 1);
+ for (p = buf; p < buf + rs; ++p) {
+ if (*p == '\n') {
+ has_newline_char = 1;
+ *(p + 1) = 0;
+ break;
+ }
+ }
+ wstd(buf);
+ }
+}
+
+
+int main(int argc, const char **argv)
+{
+ list_node_t *file;
+ int fd;
+
+ files = new_list();
+
+ arg_register_default(&add_file);
+ arg_register_flag("-", &add_stdin);
+ arg_register_flag("-l", &set_singleline_mode);
+ arg_parse_arg(argc, argv);
+
+ if (files->size == 0) {
+ list_append(files, 0);
+ }
+
+ for (file = files->first; file; file = file->next) {
+ if (file->value)
+ fd = open(file->value, OPEN_READ_ONLY, 0);
+ else
+ fd = STDIN_FD;
+
+ mode_funcs[mode](fd);
+ }
+
+ free_list(files);
+}