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 <cstdio>
#include <cstring> #include <cstring>
#include <csignal>
#include <dlfcn.h> #include <dlfcn.h>
#include <dirent.h> #include <dirent.h>
#include <unistd.h> #include <unistd.h>
@ -40,6 +41,7 @@ std::string badarguments = "Bad arguments";
// Exception defs // Exception defs
class markergoto : public std::string {}; class markergoto : public std::string {};
class pilerror : public std::string {};
std::string markergotoname; std::string markergotoname;
// Environment defs // Environment defs
@ -47,9 +49,18 @@ std::vector<std::string> cmdargs;
std::map<std::string, std::string> variables; std::map<std::string, std::string> variables;
std::map<std::string, int> markers; std::map<std::string, int> markers;
bool interactivecli; bool interactivecli;
bool catcherrs = false;
std::string lasterr = "";
std::vector<std::string> markersetqueue; std::vector<std::string> markersetqueue;
int main(int argc, char *argv[]);
std::string execline(std::string commandstr); 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 // Helper functions
bool is_float(std::string s) { bool is_float(std::string s) {
std::istringstream iss(s); std::istringstream iss(s);
@ -93,6 +104,14 @@ void do_markersetqueue(int currline) {
} }
markersetqueue = {}; 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 // Builtin functions
std::string cmd_ret(std::vector<std::string> args) { std::string cmd_ret(std::vector<std::string> args) {
@ -102,6 +121,20 @@ std::string cmd_ret(std::vector<std::string> args) {
} }
return retstring; 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) { std::string cmd_get(std::vector<std::string> args) {
if (args.size() != 2) { if (args.size() != 2) {
return badarguments; 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; //std::cout << "Running command:" << command << "!" << std::endl;
if (command == "ret") if (command == "ret")
return cmd_ret(args); return cmd_ret(args);
else if (command == "catch")
return cmd_catch(args);
else if (command == "get") else if (command == "get")
return cmd_get(args); return cmd_get(args);
else if (command == "len") else if (command == "len")
@ -419,7 +454,7 @@ std::string run_command(std::string command, std::vector<std::string> args) {
else if (command == "argc") else if (command == "argc")
return cmd_argc(args); return cmd_argc(args);
else else
return "No such command"; return nosuchcommand;
} }
// Interpreter initialiser // Interpreter initialiser
@ -500,7 +535,7 @@ std::string execline(std::string commandstr) {
} }
} }
//std::cout << "Args len: " << args.size() << std::endl; //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 // Main CLI
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
signal(SIGSEGV, sigsegv_handler);
std::string line; std::string line;
using namespace std; using namespace std;
if (argc == 1) { // Start interactive CLI if (argc == 1) { // Start interactive CLI
@ -557,8 +593,11 @@ int main(int argc, char *argv[]) {
linesit = lines.begin() + currline; linesit = lines.begin() + currline;
} else { } else {
cerr << "No such marker: \"" << markergotoname << "\" (critical)" << endl; cerr << "No such marker: \"" << markergotoname << "\" (critical)" << endl;
return 77; return 78;
} }
} catch (pilerror) {
cerr << "Line " << currline << ": " << lasterr << " (catched)" << endl;
return 77;
} }
linesit++; linesit++;
} }