commit fc552e8a9484f2dc8297ef495c35a6c35800f2c1
parent 8425a67a30ea080d91d0ae8969c37f7be70932c1
Author: Martin J. Klöckner <martin.cachari@gmail.com>
Date: Sun, 7 May 2023 01:10:00 -0300
Merge pull request #1 from mjkloeckner/dynamic_array
Improve text reading and parsing functions
Diffstat:
M | Makefile | | | 2 | +- |
M | msh.c | | | 128 | +++++++++++++++++++++++++++++++++++++++++-------------------------------------- |
2 files changed, 68 insertions(+), 62 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,5 +1,5 @@
CC := gcc
-CFLAGS := -Wall -Wshadow -pedantic -ansi -std=c99
+CFLAGS := -Wall -Wshadow -pedantic -ansi -std=c99 -O3
SRCS := $(wildcard *.c)
OBJS := $(SRCS:.c=.o)
diff --git a/msh.c b/msh.c
@@ -6,64 +6,68 @@
#include <sys/types.h>
#include <sys/wait.h>
-#define READLINE_BUFFER_INIT_SIZE 2
-#define TOKENS_BUFFER_INIT_SIZE 16
+#define READLINE_BUFFER_INIT_SIZE 128
+#define TOKENS_BUFFER_INIT_SIZE 8
+#define TOKENS_DELIM " |"
static bool run = true;
-static size_t alloc_len;
+static size_t buffer_alloc;
+static size_t tokens_alloc;
-void buffer_clear(char *buf, size_t *len) {
- for (size_t i = 0; i < *len; i++)
+void buffer_clear(char *buf) {
+ size_t len = strlen(buf);
+ for (size_t i = 0; i < len; i++)
buf[i] = '\0';
-
- *len = 0;
}
-void buffer_read_line(char *buffer, size_t *len) {
+char *buffer_read_line(char *s) {
int c;
- char *tmp;
-
- /* read line into buffer */
- while(1) {
- c = fgetc(stdin);
- if((c == '\n') || (c == EOF)) break;
-
- if((*len + 2 == alloc_len)) {
- alloc_len += alloc_len;
- if((tmp = realloc(buffer, alloc_len)) == NULL) return;
- buffer = tmp;
+ char *aux;
+ size_t used_size;
+
+ used_size = 0;
+ while (1) {
+ c = getchar();
+ if((c == '\n') || (c == EOF))
+ goto end;
+
+ if(used_size == (buffer_alloc - 1)) {
+ if(!(aux = realloc(s, buffer_alloc += buffer_alloc))) {
+ perror("msh");
+ free(s);
+ return NULL;
+ }
+ s = aux;
}
-
- buffer[(*len)++] = c;
+ s[used_size++] = c;
}
- buffer[*len] = '\0';
+end:
+ s[used_size] = '\0';
if (c == EOF) run = false;
+ return s;
}
-void buffer_split(char *b, char ***tokens, size_t *tokens_count) {
- if(b == NULL) return;
-
- char **tmp;
- size_t token_alloc;
-
- *tokens_count = 0;
-
- if(*tokens != NULL) return;
-
- *tokens = malloc((sizeof(char *) * TOKENS_BUFFER_INIT_SIZE));
- token_alloc = TOKENS_BUFFER_INIT_SIZE;
- if (*tokens == NULL) return;
-
- (*tokens)[*tokens_count] = strtok(b, " ");
- while((*tokens)[*tokens_count] != NULL) {
- (*tokens)[++(*tokens_count)] = strtok(NULL, " ");
- if (*tokens_count == token_alloc) {
- token_alloc += token_alloc;
- tmp = realloc(*tokens, sizeof(char *) * token_alloc);
- if(tmp == NULL) return;
- *tokens = tmp;
+char **buffer_split(char *b, char **t) {
+ char *p, **aux;
+ size_t tokens_count;
+
+ tokens_count = 0;
+ for(p = b; (p = strtok(p, TOKENS_DELIM)); p = NULL) {
+ if((tokens_count + 1) == tokens_alloc) {
+ tokens_alloc += tokens_alloc;
+ if(!(aux = realloc(t, sizeof(char*) * tokens_alloc))) {
+ perror("msh");
+ for(size_t i = 0; i < tokens_count; i++)
+ free(t[i]);
+ free(t);
+ return NULL;
+ }
+ t = aux;
}
+ t[tokens_count++] = p;
}
+ t[tokens_count] = NULL;
+ return t;
}
void msh_execute(char **argv) {
@@ -73,7 +77,8 @@ void msh_execute(char **argv) {
pid = fork();
if (pid == 0) {
/* child process */
- if(execvp(argv[0], argv) < 0) perror("msh");
+ if(execvp(argv[0], argv) < 0)
+ perror(argv[0]);
exit(EXIT_FAILURE);
}
@@ -89,28 +94,29 @@ void msh_execute(char **argv) {
void msh_loop(void) {
char *buffer, **tokens;
- size_t len, tokens_count;
- buffer = malloc(alloc_len = READLINE_BUFFER_INIT_SIZE);
-
- len = 0;
- while (run) {
- buffer_clear(buffer, &len);
+ buffer_alloc = READLINE_BUFFER_INIT_SIZE;
+ if(!(buffer = calloc(buffer_alloc, sizeof(char))))
+ exit(EXIT_FAILURE);
- printf("> ");
+ tokens_alloc = TOKENS_BUFFER_INIT_SIZE;
+ if(!(tokens = malloc(sizeof(char*) * tokens_alloc))) {
+ free(buffer);
+ exit(EXIT_FAILURE);
+ }
- buffer_read_line(buffer, &len);
+ while (run) {
+ /* make cusor blinking vertical bar */
+ printf("\033[5 q$ ");
+ buffer = buffer_read_line(buffer);
+ tokens = buffer_split(buffer, tokens);
- tokens = NULL;
- tokens_count = 0;
- buffer_split(buffer, &tokens, &tokens_count);
+ /* skip execute if buffer is empty */
+ if(strlen(buffer) > 0)
+ msh_execute(tokens);
- msh_execute(tokens);
+ buffer_clear(buffer);
}
-
- for (size_t token = 0; token < tokens_count; token++)
- free(tokens[token]);
-
free(tokens);
free(buffer);
}