This commit is contained in:
Pin
2022-03-31 00:19:41 -04:00
parent 28940ba8ee
commit ffec14bf49
3 changed files with 111 additions and 25 deletions

View File

@@ -9,7 +9,7 @@ build: output_dir
gcc -Wall -std=gnu99 ${RELEASE_ARGS} ${SOURCES} ${LIBRARIES} ${OUTPUT:PROG=mash} gcc -Wall -std=gnu99 ${RELEASE_ARGS} ${SOURCES} ${LIBRARIES} ${OUTPUT:PROG=mash}
debug: output_dir debug: output_dir
gcc -Wall -std=gnu99 ${SOURCES} ${LIBRARIES} ${OUTPUT:PROG=mash} gcc -Wall -std=gnu99 -g ${SOURCES} ${LIBRARIES} ${OUTPUT:PROG=mash}
output_dir: output_dir:
mkdir -p ${OUTPUT_DIR} mkdir -p ${OUTPUT_DIR}

125
msh.c
View File

@@ -1,5 +1,8 @@
#define _GNU_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h>
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <string.h> #include <string.h>
@@ -10,7 +13,10 @@
#include "msh.h" #include "msh.h"
#define clear() printf("\033[H\033[J") #define clear() printf("\033[H\033[J")
#define MATHLEN 10 #define MATHLEN 100000
static char *prompt = NULL;
static bool skipMath = false;
union pipe { union pipe {
int fileDesc[2]; int fileDesc[2];
@@ -23,43 +29,86 @@ union pipe {
static char *builtinFunctions[] = { static char *builtinFunctions[] = {
"exit", "exit",
"author", "author",
"cd" "cd",
"nomorenumbers"
}; };
int (*builtinFunc[]) (char **) = { int (*builtinFunc[]) (char **) = {
&builtinExit, &builtinExit,
&builtinAuthor, &builtinAuthor,
&builtinCD &builtinCD,
&builtinNMN
}; };
int builtinExit() { int builtinExit(char **args) {
rl_clear_history();
free(args);
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }
int builtinAuthor() { int builtinAuthor(char **args) {
static const char* message = static const char* message =
"Author: Spencer\n" "Author: Spencer\n"
"Description: A shell to promote math!\n" "Description: A shell to promote math!\n"
"Ask for the source code!\n" "Ask for the source code!\n"
"\n"; "\n";
printf("%s", message); printf("%s", message);
free(args);
return 0; return 0;
} }
int builtinCD(char **dir) { int builtinCD(char **dir) {
int status = 0; int status = 0;
if (dir != NULL) { char *oldPWD = getenv("PWD");
if (chdir(dir[1]) != 0) { char *changeDir = malloc(sizeof(char *));
if (dir[1] != NULL) {
char c = *dir[1];
switch (c) {
case '~':
changeDir = realloc(changeDir, strlen(getenv("HOME") + strlen(dir[1])));
strcpy(changeDir, getenv("HOME"));
strcat(changeDir, dir[1]+1);
break;
case '-':
changeDir = realloc(changeDir, strlen(getenv("OLDPWD")));
strcpy(changeDir, getenv("OLDPWD"));
break;
default:
changeDir = dir[1];
break;
}
if (chdir(changeDir) != 0) {
status = 1; status = 1;
printf("bash: cd: error\n"); printf("bash: cd: error\n");
} else {
setenv("PWD", dir[1], 1);
setenv("OLDPWD", oldPWD, 1);
free(prompt);
prompt = NULL;
} }
} else { } else {
if (chdir(getenv("HOME")) != 0) {
status = 1; status = 1;
printf("bash: cd: error\n"); printf("Bash: cd: error\n");
} else {
setenv("PWD", getenv("HOME"), 1);
setenv("OLDPWD", oldPWD, 1);
free(prompt);
prompt = NULL;
} }
}
free(changeDir);
changeDir = NULL;
free(dir);
return status; return status;
} }
int builtinNMN(char **args) {
skipMath = true;
free(args);
return 0;
}
void failedTest() { void failedTest() {
static const char* message = static const char* message =
"\n" "\n"
@@ -91,18 +140,21 @@ int runCommand(char *command) {
return status; return status;
} }
char **splitCMD(char *line) { char **splitCMD(const char *line) {
size_t size = 8; size_t size = 8;
size_t pos = 0; size_t pos = 0;
char **args = calloc(0, size * sizeof(char*)); char **args = malloc(size * sizeof(char*));
char *arg = NULL; char *arg = NULL;
char *lineTest = NULL;
lineTest = strdup(line);
if(line == NULL) { if(line == NULL) {
*args=NULL; *args=NULL;
return args; return args;
} }
arg = strtok(line, " \t\r\n\a"); arg = strtok(lineTest, " \t\r\n\a");
while (arg != NULL) { while (arg != NULL) {
args[pos] = arg; args[pos] = arg;
pos++; pos++;
@@ -126,6 +178,7 @@ int execCommand(char *command) {
return (*builtinFunc[i])(commandARGS); return (*builtinFunc[i])(commandARGS);
} }
} }
free(commandARGS);
return runCommand(command); return runCommand(command);
} }
@@ -165,7 +218,6 @@ char *getPrompt() {
size_t len = 0; size_t len = 0;
int status = 0; int status = 0;
static char *prompt = NULL;
static size_t promptCap = 0; static size_t promptCap = 0;
pipe(input.fileDesc); pipe(input.fileDesc);
@@ -224,17 +276,51 @@ int randomNum(int limit) {
int mathTest() { int mathTest() {
int status = 0; int status = 0;
int numAnswer = 0; long numAnswer = 0;
int num1 = randomNum(MATHLEN); int num1 = randomNum(MATHLEN);
int num2 = randomNum(MATHLEN); int num2 = randomNum(MATHLEN);
long numSolution = 0;
char *numLine = NULL; char *numLine = NULL;
printf("%d + %d = ", num1, num2);
const char mathOperation[] = {'+', '-', '*', '/'};
int randProblem = randomNum(3);
if (skipMath) {
return 0;
}
for(int i = 0; i < 1; i++) {
switch (mathOperation[randProblem]) {
case '+':
numSolution = num1 + num2;
break;
case '-':
numSolution = num1 - num2;
break;
case '*':
numSolution = num1 * num2;
break;
case '/':
numSolution = num1 / num2;
break;
}
#ifndef RELEASEBUILD
printf("Answer: %ld\n", numSolution);
#endif
printf("%d %c %d = ", num1, mathOperation[randProblem], num2);
numLine = readline(""); numLine = readline("");
sscanf(numLine, "%d", &numAnswer); sscanf(numLine, "%ld", &numAnswer);
if (numSolution != numAnswer) { // If wrong answer
status = 1;
}
}
#ifdef RELEASEBUILD #ifdef RELEASEBUILD
printf("Calculating"); printf("Calculating");
for (int i = 0; i < 3; i++){ for (int i = 0; i < 5; i++){
printf("."); printf(".");
fflush(stdout); fflush(stdout);
sleep(2); sleep(2);
@@ -242,10 +328,6 @@ int mathTest() {
printf("\n"); printf("\n");
#endif #endif
if ((num1 + num2) != numAnswer) { // If wrong answer
status = 1;
}
free(numLine); free(numLine);
return status; return status;
} }
@@ -267,6 +349,8 @@ void startShell() {
} }
free(line); free(line);
} }
free(prompt);
prompt = NULL;
} }
void handleBreak(){ void handleBreak(){
@@ -281,5 +365,6 @@ int main() {
initShell(); initShell();
signal(SIGINT, handleBreak); signal(SIGINT, handleBreak);
startShell(); startShell();
rl_clear_history();
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} }

5
msh.h
View File

@@ -1,3 +1,4 @@
int builtinExit(); int builtinExit(char **args);
int builtinAuthor(); int builtinAuthor(char **args);
int builtinCD(char **dir); int builtinCD(char **dir);
int builtinNMN(char **args);