1
0
Fork 0
mirror of https://gitlab.com/niansa/pilang2.git synced 2025-03-06 20:49:22 +01:00

Added error and SIGSEGV catching

This commit is contained in:
niansa 2020-04-13 15:31:09 +02:00
parent 42e524e5b9
commit 55e9b9897a

View file

@ -26,6 +26,7 @@ along with pilang. If not, see <https://www.gnu.org/licenses/>.
#include <cstdio>
#include <cstring>
#include <csignal>
#include <dlfcn.h>
#include <dirent.h>
#include <unistd.h>
@ -40,6 +41,7 @@ std::string badarguments = "Bad arguments";
// Exception defs
class markergoto : public std::string {};
class pilerror : public std::string {};
std::string markergotoname;
// Environment defs
@ -47,9 +49,18 @@ std::vector<std::string> cmdargs;
std::map<std::string, std::string> variables;
std::map<std::string, int> markers;
bool interactivecli;
bool catcherrs = false;
std::string lasterr = "";
std::vector<std::string> markersetqueue;
int main(int argc, char *argv[]);
std::string execline(std::string commandstr);
// Restart program on segmenation fault
void sigsegv_handler(int signal) {
std::cerr << std::endl << "Pilang crashed: signal " << signal << "=SIGSEGV (memory error)" << std::endl;
exit(177);
}
// Helper functions
bool is_float(std::string s) {
std::istringstream iss(s);
@ -93,6 +104,14 @@ void do_markersetqueue(int currline) {
}
markersetqueue = {};
}
std::string get_rstring(std::string rstring) {
if (rstring == nosuchcommand or rstring == nosuchvariable or rstring == badarguments) {
lasterr = rstring;
if (catcherrs)
throw pilerror();
}
return rstring;
}
// Builtin functions
std::string cmd_ret(std::vector<std::string> args) {
@ -102,6 +121,20 @@ std::string cmd_ret(std::vector<std::string> args) {
}
return retstring;
}
std::string cmd_catch(std::vector<std::string> args) {
std::cout << "reached" << std::endl;
if (args.size() != 1) {
return badarguments;
}
std::string boolstr = *args.begin();
if (str_lower(boolstr) == "true")
catcherrs = true;
else if (str_lower(boolstr) == "false")
catcherrs = false;
else
return badarguments;
return success;
}
std::string cmd_get(std::vector<std::string> args) {
if (args.size() != 2) {
return badarguments;
@ -376,6 +409,8 @@ std::string run_command(std::string command, std::vector<std::string> args) {
//std::cout << "Running command:" << command << "!" << std::endl;
if (command == "ret")
return cmd_ret(args);
else if (command == "catch")
return cmd_catch(args);
else if (command == "get")
return cmd_get(args);
else if (command == "len")
@ -419,7 +454,7 @@ std::string run_command(std::string command, std::vector<std::string> args) {
else if (command == "argc")
return cmd_argc(args);
else
return "No such command";
return nosuchcommand;
}
// Interpreter initialiser
@ -500,7 +535,7 @@ std::string execline(std::string commandstr) {
}
}
//std::cout << "Args len: " << args.size() << std::endl;
return run_command(command, args);
return get_rstring(run_command(command, args));
}
}
@ -509,6 +544,7 @@ std::string execline(std::string commandstr) {
// Main CLI
int main(int argc, char *argv[]) {
signal(SIGSEGV, sigsegv_handler);
std::string line;
using namespace std;
if (argc == 1) { // Start interactive CLI
@ -557,8 +593,11 @@ int main(int argc, char *argv[]) {
linesit = lines.begin() + currline;
} else {
cerr << "No such marker: \"" << markergotoname << "\" (critical)" << endl;
return 77;
return 78;
}
} catch (pilerror) {
cerr << "Line " << currline << ": " << lasterr << " (catched)" << endl;
return 77;
}
linesit++;
}