fix history navigation bug and improve code by memalloc
This commit is contained in:
parent
a058bd3ae8
commit
5a67fcb3b5
5 changed files with 56 additions and 77 deletions
8
color.c
8
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);
|
||||
|
|
40
history.c
40
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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
76
rush.c
76
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++;
|
||||
}
|
||||
for (int i = 0; i < num_arg; i++) {
|
||||
// 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";
|
||||
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++;
|
||||
args[num_arg] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
3
rush.h
3
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
|
||||
|
|
Loading…
Reference in a new issue