wip
This commit is contained in:
2
Makefile
2
Makefile
@@ -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}
|
||||||
|
|||||||
129
msh.c
129
msh.c
@@ -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 {
|
||||||
status = 1;
|
if (chdir(getenv("HOME")) != 0) {
|
||||||
printf("bash: cd: error\n");
|
status = 1;
|
||||||
|
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);
|
|
||||||
numLine = readline("");
|
const char mathOperation[] = {'+', '-', '*', '/'};
|
||||||
sscanf(numLine, "%d", &numAnswer);
|
|
||||||
|
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("");
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user