commit 5a67fcb3b5cb52dbd96acdc8972af276d9c78463
parent a058bd3ae8ac709309d4ddd9f3037d694b87bdbf
Author: night0721 <[email protected]>
Date: Sat, 10 Feb 2024 17:29:58 +0000
fix history navigation bug and improve code by memalloc
Diffstat:
M | color.c | | | 8 | +++----- |
M | history.c | | | 40 | ++++++++++++++-------------------------- |
M | history.h | | | 2 | ++ |
M | rush.c | | | 80 | ++++++++++++++++++++++++++++++++++--------------------------------------------- |
M | rush.h | | | 3 | +++ |
5 files changed, 56 insertions(+), 77 deletions(-)
diff --git a/color.c b/color.c
@@ -2,6 +2,8 @@
#include <string.h>
#include <stdlib.h>
+#include "rush.h"
+
// color str in place
void color_text(char str[], const char *color) {
int size = snprintf(NULL, 0, "\x1b[38;2;%sm%s\x1b[0m", color, str) + 1; // calculate size that is needed for colored string
@@ -9,11 +11,7 @@ void color_text(char str[], const char *color) {
fprintf(stderr, "rush: snprintf failed\n");
exit(EXIT_FAILURE);
}
- char *buf = malloc(size);
- if (buf == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
+ char *buf = memalloc(size);
snprintf(buf, size, "\x1b[38;2;%sm%s\x1b[0m", color, str); // format string to buf
strcpy(str, buf);
diff --git a/history.c b/history.c
@@ -6,12 +6,21 @@
#include <linux/limits.h>
#include "history.h"
+#include "rush.h"
#include "constants.h"
FILE *history_file;
char *histfile_path;
int cmd_count = 0;
+FILE *open_history_file(char *mode) {
+ history_file = fopen(histfile_path, mode);
+ if (history_file == NULL) {
+ fprintf(stderr, "rush: Error opening history file\n");
+ exit(EXIT_FAILURE);
+ }
+ return history_file;
+}
void check_history_file() {
char *env_home;
env_home = getenv("XDG_CONFIG_HOME");
@@ -26,11 +35,7 @@ void check_history_file() {
int env_home_len = strlen(env_home);
int histfilename_len = strlen(HISTFILE);
int path_len = env_home_len + histfilename_len + 2; // 2 for slash and null byte
- histfile_path = malloc(sizeof(char) * path_len);
- if (histfile_path == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
+ histfile_path = memalloc(sizeof(char) * path_len);
histfile_path[0] = '\0'; // initialise string
// concatenate home and history file name to a path
strcat(histfile_path, env_home);
@@ -38,21 +43,13 @@ void check_history_file() {
strcat(histfile_path, HISTFILE);
histfile_path[path_len - 1] = '\0';
if (access(histfile_path, F_OK) != 0) { // check for file existence
- history_file = fopen(histfile_path, "w"); // read and write, if doesn't exist, create
- if (history_file == NULL) {
- fprintf(stderr, "rush: Error opening history file\n");
- exit(EXIT_FAILURE);
- }
+ history_file = open_history_file("w"); // read and write, if doesn't exist, create
fclose(history_file);
}
}
void save_command_history(char *args) {
- history_file = fopen(histfile_path, "a+");
- if (history_file == NULL) {
- fprintf(stderr, "rush: Error opening history file\n");
- exit(EXIT_FAILURE);
- }
+ history_file = open_history_file("a+");
char cmd[RL_BUFSIZE];
cmd[0] = '\0';
strcat(cmd, args);
@@ -97,17 +94,8 @@ int is_duplicate(char **history, int line_count, char *line) {
}
char **get_all_history(bool check) {
- history_file = fopen(histfile_path, "r");
- if (history_file == NULL) {
- fprintf(stderr, "rush: Error opening history file\n");
- exit(EXIT_FAILURE);
- }
-
- char **history = malloc(MAX_HISTORY * sizeof(char*));
- if (history == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
+ history_file = open_history_file("r");
+ char **history = memalloc(MAX_HISTORY * sizeof(char*));
char buffer[RL_BUFSIZE];
int line_count = 0;
diff --git a/history.h b/history.h
@@ -1,6 +1,8 @@
#ifndef HISTORY_H_
#define HISTORY_H_
+extern int cmd_count;
+
void save_command_history(char *args);
void check_history_file();
char *read_command(int direction);
diff --git a/rush.c b/rush.c
@@ -14,6 +14,15 @@
#include "history.h"
#include "commands.h"
+void *memalloc(size_t size) {
+ void *ptr = memalloc(size);
+ if (!ptr) {
+ fputs("rush: Error allocating memory\n", stderr);
+ exit(EXIT_FAILURE);
+ }
+ return ptr;
+}
+
void quit_sig(int sig) {
exit(0);
}
@@ -36,12 +45,8 @@ char **setup_path_variable() {
fprintf(stderr, "rush: PATH environment variable is missing\n");
exit(EXIT_FAILURE);
}
- char *path_cpy = malloc(sizeof(char) * (strlen(envpath) + 1));
- char *path = malloc(sizeof(char) * (strlen(envpath) + 1));
- if (path_cpy == NULL || path == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
+ char *path_cpy = memalloc(sizeof(char) * (strlen(envpath) + 1));
+ char *path = memalloc(sizeof(char) * (strlen(envpath) + 1));
strcpy(path_cpy, envpath);
strcpy(path, envpath);
int path_count = 0;
@@ -53,11 +58,7 @@ char **setup_path_variable() {
path_cpy++;
}
path_count += 2; // adding one to be correct and one for terminator
- char **paths = malloc(sizeof(char *) * path_count);
- if (paths == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
+ char **paths = memalloc(sizeof(char *) * path_count);
char *token = strtok(path, ":");
int counter = 0;
while (token != NULL) {
@@ -110,12 +111,8 @@ void highlight(char *buffer, char **paths) {
if (cmd_part != NULL) {
cmd_len = cmd_part - buffer;
- char *cmd = malloc(sizeof(char) * (cmd_len + 1));
- command_without_arg = malloc(sizeof(char) * (cmd_len + 1));
- if (cmd == NULL || command_without_arg == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
+ char *cmd = memalloc(sizeof(char) * (cmd_len + 1));
+ command_without_arg = memalloc(sizeof(char) * (cmd_len + 1));
for (int i = 0; i < (cmd_part - buffer); i++) {
cmd[i] = buffer[i];
}
@@ -151,17 +148,13 @@ void highlight(char *buffer, char **paths) {
char *readline(char **paths) {
int bufsize = RL_BUFSIZE;
int position = 0;
- char *buffer = malloc(sizeof(char) * bufsize);
+ char *buffer = memalloc(sizeof(char) * bufsize);
bool moved = false;
bool backspaced = false;
bool navigated = false;
bool insertatmiddle = false;
bool replaced = false;
- if (!buffer) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
buffer[0] = '\0';
while (1) {
@@ -356,14 +349,9 @@ char *readline(char **paths) {
// split line into arguments
char **argsplit(char *line) {
int bufsize = TOK_BUFSIZE, position = 0;
- char **tokens = malloc(bufsize * sizeof(char*));
+ char **tokens = memalloc(bufsize * sizeof(char*));
char *token;
- if (!tokens) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
-
token = strtok(line, TOK_DELIM);
while (token != NULL) {
tokens[position] = token;
@@ -387,14 +375,21 @@ char **argsplit(char *line) {
char **modifyargs(char **args) {
int num_arg = 0;
+ // check if command is ls, diff, or grep, if so, add --color=auto to the arguments
+ // this is to make ls, diff, and grep have color without user typing it
+ // this is to make the shell more user friendly
while (args[num_arg] != NULL) {
num_arg++;
}
- // makes ls and diff and grep have color without user typing it
- if (strncmp(args[0], "ls", 2) == 0 || strncmp(args[0], "diff", 4) == 0 || strncmp(args[0], "grep", 4) == 0) {
- args[num_arg] = "--color=auto";
- num_arg++;
- args[num_arg] = NULL;
+ for (int i = 0; i < num_arg; i++) {
+ // makes ls and diff and grep have color without user typing it
+ if (strncmp(args[i], "ls", 2) == 0 || strncmp(args[i], "diff", 4) == 0 || strncmp(args[i], "grep", 4) == 0) {
+ for (int j = num_arg; j > i; j--) {
+ args[j + 1] = args[j];
+ }
+ args[i + 1] = "--color=auto";
+ num_arg++;
+ }
}
return args;
@@ -414,16 +409,8 @@ char *trimws(char *str) {
}
char ***pipe_argsplit(char *line) {
- char ***cmdv = malloc(sizeof(char **) * 128); // 127 commands, 1 for NULL
- if (cmdv == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
- char **cmds = malloc(sizeof(char *) * 128); // 127 arguments, 1 for NULL
- if (cmds == NULL) {
- fprintf(stderr, "rush: Error allocating memory\n");
- exit(EXIT_FAILURE);
- }
+ char ***cmdv = memalloc(sizeof(char **) * 128); // 127 commands, 1 for NULL
+ char **cmds = memalloc(sizeof(char *) * 128); // 127 arguments, 1 for NULL
int num_arg = 0;
char *pipe = strtok(line, "|");
while (pipe != NULL) {
@@ -437,6 +424,7 @@ char ***pipe_argsplit(char *line) {
for (int i = 0; i < num_arg; i++) {
char **splitted = argsplit(cmds[i]);
cmdv[i] = modifyargs(splitted);
+
}
cmdv[num_arg] = NULL;
free(cmds);
@@ -463,14 +451,14 @@ void command_loop(char **paths) {
char time[256];
strcpy(time, timestr);
color_text(time, lavender); // lavender colored time string
- char *cwd = malloc(sizeof(char) * (PATH_MAX + 2));
+ char *cwd = memalloc(sizeof(char) * (PATH_MAX + 2));
sprintf(cwd, "[%s]", cwdstr);
color_text(cwd, pink); // pink colored current directory
char arrow[32] = "ยป";
color_text(arrow, blue);
printf("%s %s %s ", time, cwd, arrow);
-
+ cmd_count = 0; // upward arrow key resets command count
line = readline(paths);
save_command_history(line);
bool has_pipe = false;
@@ -490,7 +478,7 @@ void command_loop(char **paths) {
} else {
args = argsplit(line);
args = modifyargs(args);
- status = execute(args);
+ status = execute(args, STDOUT_FILENO, OPT_FGJ);
free(args);
}
free(line);
diff --git a/rush.h b/rush.h
@@ -1,6 +1,9 @@
#ifndef RUSH_H_
#define RUSH_H_
+#include <stdio.h>
+
+void *memalloc(size_t size);
char **argsplit(char *line);
#endif