summaryrefslogtreecommitdiff
path: root/42sh/src/IO
diff options
context:
space:
mode:
Diffstat (limited to '42sh/src/IO')
-rw-r--r--42sh/src/IO/IOBackend.h27
-rw-r--r--42sh/src/IO/Makefile.am11
-rw-r--r--42sh/src/IO/string_input.c115
3 files changed, 153 insertions, 0 deletions
diff --git a/42sh/src/IO/IOBackend.h b/42sh/src/IO/IOBackend.h
new file mode 100644
index 0000000..dc190db
--- /dev/null
+++ b/42sh/src/IO/IOBackend.h
@@ -0,0 +1,27 @@
+#ifndef IOBACKEND_H
+#define IOBACKEND_H
+
+#include "utils/libstring.h"
+
+#undef DEFAULT_RW_SIZE
+
+/**
+ * @brief Represents the 'count' parameter used in read/write syscalls.
+ */
+#define DEFAULT_RW_SIZE 256
+
+/**
+ * @brief Retrieves the input provided to the main program.
+ *
+ * This function processes the program arguments and returns them as a single
+ * heap-allocated string. The returned string always ends with a null byte
+ * (`\0`).
+ *
+ * @param argc The argument count passed to main().
+ * @param argv The argument vector passed to main().
+ * @return A pointer to a `struct string` containing the input, or `NULL` on
+ * failure.
+ */
+struct string *get_input(int argc, char *argv[]);
+
+#endif /* ! IOBACKEND_H */
diff --git a/42sh/src/IO/Makefile.am b/42sh/src/IO/Makefile.am
new file mode 100644
index 0000000..27b5721
--- /dev/null
+++ b/42sh/src/IO/Makefile.am
@@ -0,0 +1,11 @@
+lib_LIBRARIES = libIO.a
+
+libIO_a_SOURCES = \
+ IOBackend.h \
+ string_input.c
+
+libIO_a_CPPFLAGS = -I$(top_srcdir)/src
+
+libIO_a_CFLAGS = -std=c99 -Werror -Wall -Wextra -Wvla -pedantic
+
+noinst_LIBRARIES = libIO.a
diff --git a/42sh/src/IO/string_input.c b/42sh/src/IO/string_input.c
new file mode 100644
index 0000000..2f252fb
--- /dev/null
+++ b/42sh/src/IO/string_input.c
@@ -0,0 +1,115 @@
+#define _POSIX_C_SOURCE 200809L
+
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "IO/IOBackend.h"
+#include "utils/env.h"
+
+static void _usage_xerror(void)
+{
+ errx(2, "Usage:\n\
+ \t./42sh [--pretty-print] [FILENAME]\n\
+ \t./42sh [-c | --pretty-print] [FILENAME]\n\
+ \t./42sh [--pretty-print] [ < FILENAME ]");
+}
+
+static struct string *_parse_input(FILE *f)
+{
+ ssize_t r = 0;
+ struct string *output = string_create(NULL);
+ char buf[DEFAULT_RW_SIZE + 1] = { 0 };
+ do
+ {
+ r = fread(buf, sizeof(char), DEFAULT_RW_SIZE, f);
+ if (r == -1)
+ {
+ fprintf(stderr, "_parse_input: fread failed!");
+ return NULL;
+ }
+ buf[r] = 0;
+ string_pushstr(output, buf);
+ } while (r >= DEFAULT_RW_SIZE);
+
+ return output;
+}
+
+static void _add_newline(struct string *s)
+{
+ if (s->data[s->length - 1] != '\n')
+ {
+ string_pushc(s, '\n');
+ }
+}
+
+struct string *get_input(int argc, char *argv[])
+{
+ int i = 1;
+ bool s_input = false;
+ FILE *f = NULL;
+ while (i < argc && argv[i][0] == '-')
+ {
+ if (strcmp(argv[i], "-c") == 0)
+ {
+ s_input = true;
+ i++;
+ continue;
+ }
+
+ if (strcmp(argv[i], "--pretty-print") == 0)
+ {
+ env_set("PRETTY_PRINT", "TRUE");
+ i++;
+ continue;
+ }
+
+ _usage_xerror();
+ }
+ if (i == argc)
+ {
+ f = stdin;
+ }
+ else
+ {
+ char *input = argv[i];
+ if (s_input)
+ {
+ f = fmemopen(input, strlen(input) + 1, "r");
+ }
+ else
+ {
+ f = fopen(input, "r");
+ env_set("0", input);
+ }
+ }
+
+ if (!f)
+ {
+ errx(2, "Invalid path!");
+ }
+
+ struct string *string_input = _parse_input(f);
+ if (f != stdin)
+ {
+ fclose(f);
+ }
+
+ int nb_args = 0;
+ i++;
+ for (; i < argc; i++)
+ {
+ nb_args++;
+ char buf[16] = { 0 };
+ sprintf(buf, "%d", nb_args);
+ env_set(buf, argv[i]);
+ }
+
+ char buf2[16] = { 0 };
+ sprintf(buf2, "%d", (s_input && nb_args > 0) ? 1 : nb_args);
+ env_set("#", buf2);
+
+ _add_newline(string_input);
+ return string_input;
+}