Compare commits

..

4 Commits

Author SHA1 Message Date
b25a5cde19 Add Bobfile 2025-04-11 19:18:11 +10:00
Maxwell Jeffress
aa91afacba Update da readme 2025-04-07 20:28:53 +10:00
Maxwell Jeffress
b2b0d96831 Merge branch 'main' of https://git.maxwellj.xyz/max/space 2025-04-07 20:25:08 +10:00
Maxwell Jeffress
d2641fc2ca Push some stuff I forgot to push 2 weeks ago 2025-04-07 20:24:48 +10:00
3 changed files with 126 additions and 54 deletions

4
Bobfile Normal file
View File

@@ -0,0 +1,4 @@
compiler "g++";
binary "space";
source "src/main.cpp";
compile;

View File

@@ -16,9 +16,11 @@ If you need to change your directory, run `cd (directory)`. If you need to exit
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. 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. 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 hard-coded into the source code, change the vector on line 59 to add directories to your path. 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. The prompt is not able to be changed. Yes, I'm forcing my opinion on you.

View File

@@ -10,12 +10,13 @@
#include <cstring> #include <cstring>
#include <limits.h> #include <limits.h>
#include <fstream> #include <fstream>
#include <signal.h>
using namespace std; 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) { void log(string input) {
cout << input << endl; cout << input << endl;
@@ -43,9 +44,30 @@ string prompt() {
return input; 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) { string findExecutable(string executable) {
for (int i = 0; i < builtInFunctions.size(); i++) { for (int i = 0; i < functions.size(); i++) {
if (builtInFunctions[i] == executable) { if (functions[i] == executable) {
return executable; return executable;
} }
} }
@@ -56,7 +78,7 @@ string findExecutable(string executable) {
return executable; return executable;
} }
string output; string output;
vector<string> path = {"/bin", "/usr/bin", "/usr/local/bin"}; vector<string> path = getPath();
for (int i = 0; i < path.size(); i++) { for (int i = 0; i < path.size(); i++) {
output = path[i] + "/" + executable; output = path[i] + "/" + executable;
if (filesystem::exists(output)) { if (filesystem::exists(output)) {
@@ -139,30 +161,91 @@ vector<string> tokeniseSubstitutions(string input) {
} }
int runProcess(vector<string> args) { int runProcess(vector<string> args) {
pid_t pid = fork(); if (args[0] == "exit") {
if (pid == -1) { exit(0);
cerr << "Fork failed!" << endl; } else if (args[0] == "cd") {
if (args.size() == 1) {
log("cd requires an argument");
return 1;
} else {
filesystem::current_path(args[1]);
}
} 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);
}
return -1; return -1;
} }
if (pid == 0) { return 0;
vector<char*> cargs; }
cargs.push_back(const_cast<char*>(args[0].c_str()));
for (int i = 1; i < args.size(); i++) { void runScript(string script) {
cargs.push_back(const_cast<char*>(args[i].c_str())); 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));
} }
cargs.push_back(nullptr);
execvp(args[0].c_str(), cargs.data());
cerr << "Execution failed with error " << strerror(errno) << endl;
_exit(1);
} }
int status; scriptFile.close();
waitpid(pid, &status, 0);
if (WIFEXITED(status)) {
return WEXITSTATUS(status);
}
return -1;
} }
void doStartup() { void doStartup() {
@@ -186,7 +269,13 @@ void doStartup() {
} }
} }
void handler(int signum);
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
signal(SIGINT, handler);
if (argc > 1) {
runScript(argv[2]);
}
doStartup(); doStartup();
bool continueLoop = true; bool continueLoop = true;
while (continueLoop) { while (continueLoop) {
@@ -196,33 +285,6 @@ int main(int argc, char *argv[]) {
} }
vector<string> tokens = tokenise(input); vector<string> tokens = tokenise(input);
auto path = filesystem::current_path(); 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()) { if (tokens.empty()) {
continue; continue;
} }
@@ -233,3 +295,7 @@ int main(int argc, char *argv[]) {
} }
return 0; return 0;
} }
void handler(int signum) {
main(1, nullptr);
}