Browse Source

Alias functions

master
alistair 5 years ago
parent
commit
20966522ca
  1. 191
      main.c
  2. 32
      main.h
  3. 7
      run.c
  4. 113
      util.c
  5. 6
      util.h

191
main.c

@ -1,118 +1,149 @@ @@ -1,118 +1,149 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#include "error.h"
#include "run.h"
#include "main.h"
#include "util.h"
#define INITIAL_LINE_BUFFER 80
#define INITIAL_WORD_SIZE 80
#define NUM_BUILTINS 2
int readline(FILE* in, char **out) {
int size_of_buffer = INITIAL_LINE_BUFFER;
char *buffer = calloc(size_of_buffer, sizeof(char));
char character;
int count = 0;
while (true) {
character = fgetc(in);
if (character == EOF) {
buffer[count] = '\0';
*out = buffer;
return EOF;
}
if (character == '\n') {
buffer[count] = '\0';
*out = buffer;
int get_alias(Alias *alias, State *state, char *name) {
for (int i = 0; i < state->num_aliases; i++) {
if (!strcmp(name, state->aliases[i].name)) {
*alias = state->aliases[i];
return ER_SUCCESS;
} else {
if (count == (size_of_buffer - 3)) {
buffer = reallocarray(buffer, (size_of_buffer *= 2),
sizeof(char));
if (!buffer) {
return ER_ALLOC;
}
}
buffer[count] = character;
count++;
}
}
return ER_FAILURE;
}
int split_string(char **sep_string[], int *num, char *string, char delim) {
char **word_list = calloc(10, sizeof(char*));
int word_size;
char *word = calloc((word_size=INITIAL_WORD_SIZE), sizeof(char));
int num_words = 0;
int word_length = 0;
int add_alias(State* state, char *name, char *substitution) {
Alias alias;
alias.name = name;
alias.substitution = substitution;
Alias throw;
for (int i = 0; true; i++) {
if (string[i] == '\0') {
if (word_length) {
word_list[num_words] = word;
num_words++;
}
if (get_alias(&throw, state, name)) {
// add it if it doesnt exist
*sep_string = word_list;
*num = num_words;
return ER_SUCCESS;
}
state->aliases[state->num_aliases] = alias;
state->num_aliases++;
}
if (string[i] == delim) {
if (word_length) {
word_list[num_words] = word;
return ER_SUCCESS;
}
num_words++;
word_length = 0;
word = calloc((word_size=INITIAL_WORD_SIZE), sizeof(char));
int del_alias(State *state, char *name) {
// read the list until the alias is found, then
// shuffle all the alias definitions down by one
bool move = false;
for (int i = 0; i < state->num_aliases; i++) {
if (move) {
if (i < state->num_aliases -1) {
state->aliases[i] = state->aliases[i + 1];
} else {
memset(&state->aliases[i], 0, sizeof(Alias));
}
} else {
word[word_length] = string[i];
word_length++;
if (word_length == word_size - 2) {
word = reallocarray(word, word_size *= 2, sizeof(char));
if (!strcmp(name, state->aliases[i].name)) {
move = true;
}
}
}
}
return ER_FAILURE;
if (move) {
state->num_aliases--;
return ER_SUCCESS;
} else {
return ER_FAILURE;
}
}
int list_aliases(State *state) {
for (int i = 0; i < state->num_aliases; i++) {
Alias alias = state->aliases[i];
printf("alias %s=%s\n", alias.name, alias.substitution);
}
return ER_SUCCESS;
}
int check_builtins(char *args[]) {
int check_builtins(State *state, int num_args, char *args[]) {
char *builtins[NUM_BUILTINS] = {
"cd",
"alias"
};
if (!strcmp(args[0], "cd")) {
if (args[1] == 0) {
if (num_args == 1) {
chdir(getenv("HOME"));
return ER_SUCCESS;
}
if (args[2] != 0) {
if (num_args != 2) {
return ER_FAILURE;
}
chdir(args[1]);
}
if (!strcmp(args[0], "alias")) {
Alias alias;
// list aliases
if (args[1] == 0) {
list_aliases(state);
return ER_SUCCESS;
}
// add new alias
if (num_args == 2) {
if (!get_alias(&alias, state, args[1])) {
printf("alias %s=%s\n", alias.name, alias.substitution);
return ER_SUCCESS;
}
if (num_args > 1) {
char *substitution;
char **new_split;
int err = join_stirng(&substitution, num_args - 1, args + 1, " ");
if (err) {
return err;
}
int eqcount = 0;
int num_parts;
err = split_string(&new_split, &num_parts, substitution, '=');
// exit if alias contains an =
if (num_parts != 2 || err) {
return ER_FAILURE;
}
err = add_alias(state, new_split[0], new_split[1]);
return err;
}
}
}
return ER_FAILURE;
}
int repl(void) {
int run_command(State *state, int argc, char *argv[]) {
pid_t child;
if (argc == 0) {
return ER_FAILURE;
}
if (check_builtins(state, argc, argv)) {
execute(stdin, stdout, argv, &child);
waitpid(child, NULL, 0);
}
return ER_SUCCESS;
}
int repl(State* state) {
while (true) {
char *line;
printf("$ ");
if (readline(stdin, &line)) {
return ER_SUCCESS;
}
@ -121,17 +152,13 @@ int repl(void) { @@ -121,17 +152,13 @@ int repl(void) {
int num_words;
split_string(&sep_string, &num_words, line, ' ');
pid_t child;
if (check_builtins(sep_string)) {
execute(stdin, stdout, sep_string, &child);
}
waitpid(child, NULL, 0);
run_command(state, num_words, sep_string);
for (int i = 0; i < num_words; i++) {
free(sep_string[i]);
}
free(sep_string);
free(line);
}
@ -149,11 +176,15 @@ int main(int argc, char** argv) { @@ -149,11 +176,15 @@ int main(int argc, char** argv) {
" |\n",
" _|}\n"};
State *state = calloc(1, sizeof(state));
state->aliases = calloc(INITIAL_NUM_ALIASES, sizeof(struct Alias));
state->num_aliases = 0;
for (int i = 0; i < 8; i ++) {
printf("%s", chicken[i]);
}
repl();
repl(state);
return ER_SUCCESS;
}

32
main.h

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#ifndef MAINH
#define MAINH
#define INITIAL_LINE_BUFFER 80
#define INITIAL_WORD_SIZE 80
#define INITIAL_NUM_ALIASES 50
#define NUM_BUILTINS 2
struct Alias {
char *name;
char *substitution;
};
struct State {
struct Alias* aliases;
int num_aliases;
};
typedef struct State State;
typedef struct Alias Alias;
#endif

7
run.c

@ -1,12 +1,5 @@ @@ -1,12 +1,5 @@
#include "run.h"
/* Contains builtin functions and code for executing system programs */
int change_dir(char *dir) {
return chdir(dir);
}
/* Fork and exec a command given in args taking input from in and sending
* output to out. The arguments array must end in a NULL.
*

113
util.c

@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
#include "util.h"
int readline(FILE* in, char **out) {
int size_of_buffer = INITIAL_LINE_BUFFER;
char *buffer = calloc(size_of_buffer, sizeof(char));
char character;
int count = 0;
while (true) {
character = fgetc(in);
if (character == EOF) {
buffer[count] = '\0';
*out = buffer;
return EOF;
}
if (character == '\n') {
buffer[count] = '\0';
*out = buffer;
return ER_SUCCESS;
} else {
if (count == (size_of_buffer - 3)) {
buffer = reallocarray(buffer, (size_of_buffer *= 2),
sizeof(char));
if (!buffer) {
return ER_ALLOC;
}
}
buffer[count] = character;
count++;
}
}
}
/* Join an array of strings together using the delim string as the joiner. */
int join_stirng(char **joined, int arr_len, char *sep_stirng[], char *delim) {
int length = 0;
int delim_len = strlen(delim);
char *new_string = calloc(INITIAL_LINE_BUFFER, sizeof(char));
int stringsize = INITIAL_LINE_BUFFER;
for (int i = 0; i < arr_len; i++) {
if (length == stringsize - 2) {
new_string = reallocarray(new_string, stringsize *= 2, sizeof(char));
}
int len = strlen(sep_stirng[i]);
for (int k = 0; k < len; k++) {
new_string[length + k] = sep_stirng[i][k];
}
length += len;
if (sep_stirng[i+1] == 0) {
*joined = new_string;
return ER_SUCCESS;
} else {
for (int k = 0; k < delim_len; k++) {
new_string[length + k] = delim[k];
}
length += delim_len;
}
}
return ER_FAILURE;
}
/* Take a string and split it into an array of strings, separate by the delim
* character.
*/
int split_string(char **sep_string[], int *num, char *string, char delim) {
char **word_list = calloc(10, sizeof(char*));
int word_size;
char *word = calloc((word_size=INITIAL_WORD_SIZE), sizeof(char));
int num_words = 0;
int word_length = 0;
for (int i = 0; true; i++) {
if (string[i] == '\0') {
if (word_length) {
word_list[num_words] = word;
num_words++;
}
*sep_string = word_list;
*num = num_words;
return ER_SUCCESS;
}
if (string[i] == delim) {
if (word_length) {
word_list[num_words] = word;
num_words++;
word_length = 0;
word = calloc((word_size=INITIAL_WORD_SIZE), sizeof(char));
}
} else {
word[word_length] = string[i];
word_length++;
if (word_length == word_size - 2) {
word = reallocarray(word, word_size *= 2, sizeof(char));
}
}
}
return ER_FAILURE;
}

6
util.h

@ -1,7 +1,13 @@ @@ -1,7 +1,13 @@
#include "main.h"
#include "error.h"
#ifndef UTILH
#define UTILH
int readline(FILE* in, char **out);
int split_string(char **sep_string[], int *num, char *string, char delim);
int join_stirng(char **joined, int arr_len, char *sep_stirng[], char *delim);
#endif

Loading…
Cancel
Save