diff --git a/src/main.cc b/src/main.cc index ee75368..cbf542b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,4 +1,77 @@ +#include +#include +#include +#include +#include +#include +#include + +VALUE svi_ruby_protect_eval_string_rescue(VALUE exception, VALUE exception_object) +{ + *(bool *)exception = true; + fprintf(stderr, "Unhandled exception: %s\n", + rb_obj_classname(exception_object)); + return Qnil; +} + +VALUE ruby_protect_eval_string(const char * ruby_expression, bool * exception) +{ + *exception = false; + return rb_rescue((VALUE(*)(...))rb_eval_string, (VALUE)ruby_expression, + (VALUE(*)(...))svi_ruby_protect_eval_string_rescue, (VALUE)exception); +} + +static char * read_file(const char * filename) +{ + int fd = ::open(filename, O_RDONLY, 0); + if (fd < 0) + { + return nullptr; + } + off_t size = ::lseek(fd, 0, SEEK_END); + if (size <= 0) + { + return nullptr; + } + ::lseek(fd, 0, SEEK_SET); + char * buffer = new char[size]; + off_t n_bytes_read = 0u; + for (;;) + { + off_t rd_size = ::read(fd, &buffer[n_bytes_read], size - n_bytes_read); + if (rd_size <= 0) + break; + n_bytes_read += rd_size; + if (n_bytes_read >= size) + break; + } + ::close(fd); + if (n_bytes_read == size) + { + return buffer; + } + else + { + delete[] buffer; + return nullptr; + } +} + int main(int argc, char * argv[]) { - return 0; + static const char * ruby_startup_file = SHARE_DIR "/svi.rb"; + bool exception = false; + char * ruby_startup = read_file(ruby_startup_file); + if (ruby_startup == nullptr) + { + fprintf(stderr, "Error opening %s\n", ruby_startup_file); + return 1; + } + { + RUBY_INIT_STACK; + ruby_init(); + ruby_protect_eval_string(ruby_startup, &exception); + } + delete[] ruby_startup; + return exception ? 1 : 0; }