Compare commits
6 Commits
862336da96
...
main
Author | SHA1 | Date | |
---|---|---|---|
b25a5cde19 | |||
![]() |
aa91afacba | ||
![]() |
b2b0d96831 | ||
![]() |
d2641fc2ca | ||
![]() |
f01ea8af6d | ||
cb9a5ea202 |
4
Bobfile
Normal file
4
Bobfile
Normal file
@@ -0,0 +1,4 @@
|
||||
compiler "g++";
|
||||
binary "space";
|
||||
source "src/main.cpp";
|
||||
compile;
|
14
README.md
14
README.md
@@ -2,11 +2,11 @@
|
||||
|
||||
## What is space?
|
||||
|
||||
Space is a shell. Not much else.
|
||||
Space is a shell. There is a simple substitutions feature, which can substitute something for something else.
|
||||
|
||||
## How to use?
|
||||
|
||||
1. Compile (`g++ src/main.cpp -o space`).
|
||||
1. Compile (`g++ src/main.cpp -o space`). (may differ by OS or personal preference, this works for Linux)
|
||||
|
||||
2. Run the outputted binary (`space`).
|
||||
|
||||
@@ -14,6 +14,14 @@ Space is a shell. Not much else.
|
||||
|
||||
If you need to change your directory, run `cd (directory)`. If you need to exit the shell, type `exit`.
|
||||
|
||||
The path is hard-coded into the source code, change the vector on line 40 to add directories to your path.
|
||||
If you would like to create a substitution, type `sub (string) (anotherstring)`. List all your substitutions with `listsubs`. By default, `ls` is substituted with `ls -l`. If you'd like to make your substitutions include extra command line arguments, write your arguments inside quotation marks.
|
||||
|
||||
Change environment variables with `set key value`. At present there is no way to access environment variables.
|
||||
|
||||
A file located at ~/.config/space/Spacefile is essentially a script that will run on startup. Add any commands or substitutions that you would like in this file. These will be run for you.
|
||||
|
||||
The path is set with the $PATH environment variable.
|
||||
|
||||
The prompt is not able to be changed. Yes, I'm forcing my opinion on you.
|
||||
|
||||
If you want to run an executable in your current directory, there's no need for the ./ (keep in mind Space will prioritise local executables over ones in the path)
|
||||
|
172
src/main.cpp
172
src/main.cpp
@@ -10,12 +10,13 @@
|
||||
#include <cstring>
|
||||
#include <limits.h>
|
||||
#include <fstream>
|
||||
#include <signal.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
vector<string> builtInFunctions = {"exit", "cd", "sub"};
|
||||
vector<string> functions = {"exit", "cd", "sub", "listsubs", "set", "get", "run"};
|
||||
|
||||
vector<pair<string, vector<string>>> substitutions = {{"ls", {"ls", "--color"}}};
|
||||
vector<pair<string, vector<string>>> substitutions;
|
||||
|
||||
void log(string input) {
|
||||
cout << input << endl;
|
||||
@@ -43,9 +44,30 @@ string prompt() {
|
||||
return input;
|
||||
}
|
||||
|
||||
vector<string> getPath() {
|
||||
string pathstr = getenv("PATH");
|
||||
if (pathstr == "") {
|
||||
log("WARNING! SPACE CANNOT FIND THE PATH! Please ensure your path is set as an environment variable in your Spacefile, or one of Space's parents has set the PATH environment variable. For now, enjoy the default path :)");
|
||||
} else {
|
||||
vector<string> path;
|
||||
string buffer;
|
||||
for (int i = 0; i < pathstr.size(); i++) {
|
||||
if (pathstr[i] == ':') {
|
||||
path.push_back(buffer);
|
||||
buffer = "";
|
||||
} else {
|
||||
buffer += pathstr[i];
|
||||
}
|
||||
}
|
||||
path.push_back(buffer);
|
||||
return path;
|
||||
}
|
||||
return {"/bin", "/usr/bin", "/usr/local/bin"};
|
||||
}
|
||||
|
||||
string findExecutable(string executable) {
|
||||
for (int i = 0; i < builtInFunctions.size(); i++) {
|
||||
if (builtInFunctions[i] == executable) {
|
||||
for (int i = 0; i < functions.size(); i++) {
|
||||
if (functions[i] == executable) {
|
||||
return executable;
|
||||
}
|
||||
}
|
||||
@@ -56,7 +78,7 @@ string findExecutable(string executable) {
|
||||
return executable;
|
||||
}
|
||||
string output;
|
||||
vector<string> path = {"/bin", "/usr/bin", "/usr/local/bin"};
|
||||
vector<string> path = getPath();
|
||||
for (int i = 0; i < path.size(); i++) {
|
||||
output = path[i] + "/" + executable;
|
||||
if (filesystem::exists(output)) {
|
||||
@@ -139,30 +161,91 @@ vector<string> tokeniseSubstitutions(string input) {
|
||||
}
|
||||
|
||||
int runProcess(vector<string> args) {
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
cerr << "Fork failed!" << endl;
|
||||
return -1;
|
||||
}
|
||||
if (pid == 0) {
|
||||
vector<char*> cargs;
|
||||
cargs.push_back(const_cast<char*>(args[0].c_str()));
|
||||
for (int i = 1; i < args.size(); i++) {
|
||||
cargs.push_back(const_cast<char*>(args[i].c_str()));
|
||||
if (args[0] == "exit") {
|
||||
exit(0);
|
||||
} else if (args[0] == "cd") {
|
||||
if (args.size() == 1) {
|
||||
log("cd requires an argument");
|
||||
return 1;
|
||||
} else {
|
||||
filesystem::current_path(args[1]);
|
||||
}
|
||||
cargs.push_back(nullptr);
|
||||
execvp(args[0].c_str(), cargs.data());
|
||||
|
||||
cerr << "Execution failed with error " << strerror(errno) << endl;
|
||||
_exit(1);
|
||||
}
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
} else if (args[0] == "set") {
|
||||
if (args.size() < 3) {
|
||||
log("set requires 2 arguments");
|
||||
return 1;
|
||||
}
|
||||
string envStr = (args[1] + "=" + args[2]);
|
||||
char* cEnvStr = strdup(envStr.c_str());
|
||||
putenv(cEnvStr);
|
||||
} else if (args[0] == "get") {
|
||||
if (args.size() < 2) {
|
||||
log("get requires an argument");
|
||||
return 1;
|
||||
}
|
||||
char* value = getenv(args[1].c_str());
|
||||
if (value == nullptr) {
|
||||
log("Environment variable " + args[1] + " not found");
|
||||
return 1;
|
||||
}
|
||||
cout << value << endl;
|
||||
} else if (args[0] == "sub") {
|
||||
if (args.size() < 3) {
|
||||
log("substitute requires 2 arguments");
|
||||
return 1;
|
||||
}
|
||||
vector<string> subArgs = tokeniseSubstitutions(args[2]);
|
||||
substitutions.push_back({args[1], subArgs});
|
||||
} else if (args[0] == "listsubs") {
|
||||
log("Substitutions:");
|
||||
for (int i = 0; i < substitutions.size(); i++) {
|
||||
string substring;
|
||||
for (int j = 0; j < substitutions[i].second.size(); j++) {
|
||||
substring += substitutions[i].second[j] + " ";
|
||||
}
|
||||
cout << substitutions[i].first << " -> " << substring << endl;
|
||||
}
|
||||
} else {
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
cerr << "Fork failed!" << endl;
|
||||
return -1;
|
||||
}
|
||||
if (pid == 0) {
|
||||
vector<char*> cargs;
|
||||
cargs.push_back(const_cast<char*>(args[0].c_str()));
|
||||
for (int i = 1; i < args.size(); i++) {
|
||||
cargs.push_back(const_cast<char*>(args[i].c_str()));
|
||||
}
|
||||
cargs.push_back(nullptr);
|
||||
execvp(args[0].c_str(), cargs.data());
|
||||
|
||||
cerr << "Execution failed with error " << strerror(errno) << endl;
|
||||
_exit(1);
|
||||
}
|
||||
int status;
|
||||
waitpid(pid, &status, 0);
|
||||
|
||||
if (WIFEXITED(status)) {
|
||||
return WEXITSTATUS(status);
|
||||
if (WIFEXITED(status)) {
|
||||
return WEXITSTATUS(status);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void runScript(string script) {
|
||||
string scriptLine;
|
||||
ifstream scriptFile(script);
|
||||
while (getline(scriptFile, scriptLine)) {
|
||||
vector<string> tokens = tokenise(scriptLine);
|
||||
if (tokens.empty()) continue;
|
||||
int returnCode = runProcess(tokens);
|
||||
if (returnCode != 0) {
|
||||
log("Script error:\nCommand " + tokens[0] + " failed with exit code " + to_string(returnCode));
|
||||
}
|
||||
}
|
||||
scriptFile.close();
|
||||
}
|
||||
|
||||
void doStartup() {
|
||||
@@ -186,7 +269,13 @@ void doStartup() {
|
||||
}
|
||||
}
|
||||
|
||||
void handler(int signum);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
signal(SIGINT, handler);
|
||||
if (argc > 1) {
|
||||
runScript(argv[2]);
|
||||
}
|
||||
doStartup();
|
||||
bool continueLoop = true;
|
||||
while (continueLoop) {
|
||||
@@ -196,33 +285,6 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
vector<string> tokens = tokenise(input);
|
||||
auto path = filesystem::current_path();
|
||||
if (tokens[0] == "exit") {
|
||||
exit(0);
|
||||
} else if (tokens[0] == "cd") {
|
||||
if (tokens.size() == 1) {
|
||||
log("cd requires an argument");
|
||||
} else {
|
||||
filesystem::current_path(tokens[1]);
|
||||
}
|
||||
continue;
|
||||
} else if (tokens[0] == "sub") {
|
||||
if (tokens.size() < 3) {
|
||||
log("substitute requires 2 arguments");
|
||||
continue;
|
||||
}
|
||||
vector<string> args = tokeniseSubstitutions(tokens[2]);
|
||||
substitutions.push_back({tokens[1], args});
|
||||
continue;
|
||||
} else if (tokens[0] == "listsubs") {
|
||||
log("Substitutions:");
|
||||
for (int i = 0; i < substitutions.size(); i++) {
|
||||
string substring;
|
||||
for (int j = 0; j < substitutions[i].second.size(); j++) {
|
||||
substring += substitutions[i].second[j] + " ";
|
||||
}
|
||||
cout << substitutions[i].first << " -> " << substring << endl;
|
||||
}
|
||||
}
|
||||
if (tokens.empty()) {
|
||||
continue;
|
||||
}
|
||||
@@ -233,3 +295,7 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void handler(int signum) {
|
||||
main(1, nullptr);
|
||||
}
|
||||
|
Reference in New Issue
Block a user