static mrb_value mrb_file_s_rename(mrb_state *mrb, mrb_value obj) { mrb_value from, to; char *src, *dst; mrb_get_args(mrb, "SS", &from, &to); src = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &from), -1); dst = mrb_locale_from_utf8(mrb_string_value_cstr(mrb, &to), -1); if (rename(src, dst) < 0) { #if defined(_WIN32) || defined(_WIN64) if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) { mrb_locale_free(src); mrb_locale_free(dst); return mrb_fixnum_value(0); } #endif mrb_locale_free(src); mrb_locale_free(dst); mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); } mrb_locale_free(src); mrb_locale_free(dst); return mrb_fixnum_value(0); }
mrb_value mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) { mrb_value path = mrb_nil_value(); mrb_value mode = mrb_nil_value(); mrb_int fd, flags, perm = -1; const char *pat; int modenum; mrb_get_args(mrb, "S|Si", &path, &mode, &perm); if (mrb_nil_p(mode)) { mode = mrb_str_new_cstr(mrb, "r"); } if (perm < 0) { perm = 0666; } pat = mrb_string_value_cstr(mrb, &path); flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); modenum = mrb_io_flags_to_modenum(mrb, flags); fd = open(pat, modenum, perm); if (fd == -1) { mrb_sys_fail(mrb, pat); } return mrb_fixnum_value(fd); }
mrb_value plus(mrb_state *mrb, mrb_value self) { mrb_value arg1; mrb_value arg2; mrb_value ret; mrb_get_args(mrb, "oo", &arg1, &arg2); // ret = mrb_funcall(mrb, arg1, "+", 1, arg2); if(mrb_type(arg1)==MRB_TT_FIXNUM && mrb_type(arg2)==MRB_TT_FIXNUM){ return mrb_fixnum_value(mrb_fixnum(arg1) + mrb_fixnum(arg2)); } if(mrb_type(arg1)==MRB_TT_STRING && mrb_type(arg2)==MRB_TT_STRING){ // printf("arg1=%s\n", mrb_string_value_cstr(mrb, &arg1)); // printf("arg2=%s\n", mrb_string_value_cstr(mrb, &arg2)); char* s1 = mrb_string_value_cstr(mrb, &arg1); char* s2 = mrb_string_value_cstr(mrb, &arg2); char* s_ret = malloc(strlen(s1)+strlen(s2)+1); s_ret[0] = '\0'; strcat(s_ret, s1); strcat(s_ret, s2); ret = mrb_str_new_cstr(mrb, s_ret); free(s_ret); return ret; } return mrb_nil_value(); }
mrb_value mrb_serialport_open(mrb_state *mrb, mrb_value self) { int fd; mrb_value mrb_portname = IV_GET("@port_name"); mrb_value mrb_baud = IV_GET("@baud"); mrb_value mrb_blocking = IV_GET("@blocking"); const char *portname = mrb_string_value_cstr(mrb, &mrb_portname); unsigned int baud = mrb_fixnum(mrb_baud); fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC); if (fd < 0) { update_error(mrb, self); mrb_raise(mrb, E_RUNTIME_ERROR, strerror(errno)); } if (!isatty(fd)) { update_error(mrb, self); mrb_raise(mrb, E_RUNTIME_ERROR, strerror(errno)); } if (set_interface_attribs(fd, baud, 0)) { update_error(mrb, self); mrb_raise(mrb, E_RUNTIME_ERROR, strerror(errno)); } if (set_blocking(fd, mrb_bool(mrb_blocking) ? 1 : 0) != 0) { IV_SET("@error", mrb_str_new_cstr(mrb, "Could not set blocking behavior")); mrb_raise(mrb, E_RUNTIME_ERROR, "Could not set blocking behavior"); } IV_SET("@fd", mrb_fixnum_value(fd)); return self; }
mrb_value mrb_io_initialize(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; mrb_int fd, flags; mrb_value mode, opt; DATA_TYPE(io) = &mrb_io_type; DATA_PTR(io) = NULL; mode = opt = mrb_nil_value(); mrb_get_args(mrb, "i|So", &fd, &mode, &opt); if (mrb_nil_p(mode)) { mode = mrb_str_new_cstr(mrb, "r"); } if (mrb_nil_p(opt)) { opt = mrb_hash_new(mrb); } flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); mrb_iv_set(mrb, io, mrb_intern(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); mrb_iv_set(mrb, io, mrb_intern(mrb, "@pos"), mrb_fixnum_value(0)); fptr = DATA_PTR(io); if (fptr == NULL) { fptr = mrb_io_alloc(mrb); } fptr->fd = fd; DATA_PTR(io) = fptr; return io; }
/* * call-seq: * LCD.draw(x, y, str) # => nil * * Draw the string at specified coordinate of LCD. * * Parameters: * +x+ X-coordinate of the string left edge * +y+ Y-coordinate of the string top edge * +str+ The target for drawing. * * Returns nil. */ static mrb_value mrb_lcd_draw_string(mrb_state *mrb, mrb_value self) { mrb_value obj, str; mrb_int x, y; mrb_int fw, fh; mrb_int cw, ch; mrb_lcd_get_font_size(mrb, self, &fw, &fh); cw = EV3_LCD_WIDTH / fw; ch = EV3_LCD_HEIGHT / fh; mrb_get_args(mrb, "iio", &x, &y, &obj); if (mrb_string_p(obj)) { str = obj; } else { str = mrb_funcall(mrb, obj, "to_s", 0); } ev3_lcd_draw_string(mrb_string_value_cstr(mrb, &str), x*cw, y*ch); return mrb_nil_value(); }
mrb_value mrb_f_system(mrb_state *mrb, mrb_value klass) { int ret; mrb_value *argv, pname; const char *path; int argc; RETSIGTYPE (*chfunc)(int); fflush(stdout); fflush(stderr); mrb_get_args(mrb, "*", &argv, &argc); if (argc == 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); } pname = argv[0]; #ifdef SIGCHLD chfunc = signal(SIGCHLD, SIG_DFL); #endif path = mrb_string_value_cstr(mrb, &pname); ret = system(path); if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) { return mrb_true_value(); } return mrb_false_value(); }
static mrb_value org_name_setter(mrb_state *mrb, mrb_value self) { mrb_value s; mrb_get_args(mrb, "S", &s); al_set_org_name(mrb_string_value_cstr(mrb, &s)); return s; }
static mrb_value mrb_file_s_rename(mrb_state *mrb, mrb_value obj) { mrb_value from, to; const char *src, *dst; mrb_get_args(mrb, "SS", &from, &to); src = mrb_string_value_cstr(mrb, &from); dst = mrb_string_value_cstr(mrb, &to); if (rename(src, dst) < 0) { if (CHMOD(dst, 0666) == 0 && UNLINK(dst) == 0 && rename(src, dst) == 0) { return mrb_fixnum_value(0); } mrb_sys_fail(mrb, mrb_str_to_cstr(mrb, mrb_format(mrb, "(%S, %S)", from, to))); } return mrb_fixnum_value(0); }
static int io_open(mrb_state *mrb, mrb_value path, int flags, int perm) { const char *pat; int modenum; pat = mrb_string_value_cstr(mrb, &path); modenum = mrb_io_flags_to_modenum(mrb, flags); return open(pat, modenum, perm); }
static mrb_value ctx_set_error_file(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; mrb_value error_file; mrb_get_args(mrb, "S", &error_file); mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@error_file"), error_file); ctx->errfile = mrb_string_value_cstr(mrb, &error_file); return error_file; }
static mrb_value ctx_set_error_method(mrb_state *mrb, mrb_value self) { grn_ctx *ctx = (grn_ctx *)mrb->ud; mrb_value error_method; mrb_get_args(mrb, "S", &error_method); mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@error_method"), error_method); ctx->errfunc = mrb_string_value_cstr(mrb, &error_method); return error_method; }
static mrb_encoding * to_encoding(mrb_state *mrb, mrb_value enc) { int idx; //StringValue(enc); mrb_string_value(mrb, &enc); if (!mrb_enc_asciicompat(mrb, mrb_enc_get(mrb, enc))) { mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid name encoding (non ASCII)"); } //idx = mrb_enc_find_index(StringValueCStr(enc)); idx = mrb_enc_find_index(mrb, mrb_string_value_cstr(mrb, &enc)); if (idx < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "unknown encoding name - %s", RSTRING_PTR(enc)); } return mrb_enc_from_index(mrb, idx); }
static mrb_value mrb_file_s_unlink(mrb_state *mrb, mrb_value obj) { mrb_value *argv; mrb_value pathv; mrb_int argc, i; const char *path; mrb_get_args(mrb, "*", &argv, &argc); for (i = 0; i < argc; i++) { pathv = mrb_convert_type(mrb, argv[i], MRB_TT_STRING, "String", "to_str"); path = mrb_string_value_cstr(mrb, &pathv); if (UNLINK(path) < 0) { mrb_sys_fail(mrb, path); } } return mrb_fixnum_value(argc); }
/* set_text * * Parameters: * - value: const char * */ mrb_value mrb_SDL_SDLMessageBoxButtonData_set_text(mrb_state* mrb, mrb_value self) { SDL_MessageBoxButtonData * native_self = mruby_unbox_SDL_MessageBoxButtonData(self); mrb_value ruby_field; mrb_get_args(mrb, "o", &ruby_field); /* type checking */ if (!mrb_obj_is_kind_of(mrb, ruby_field, mrb->string_class)) { mrb_raise(mrb, E_TYPE_ERROR, "String expected"); return mrb_nil_value(); } const char * native_field = mrb_string_value_cstr(mrb, &ruby_field); native_self->text = native_field; return ruby_field; }
/* set_name * * Parameters: * - value: const char * */ mrb_value mrb_SDL_SDLRendererInfo_set_name(mrb_state* mrb, mrb_value self) { struct SDL_RendererInfo * native_self = mruby_unbox_SDL_RendererInfo(self); mrb_value ruby_field; mrb_get_args(mrb, "o", &ruby_field); /* type checking */ if (!mrb_obj_is_kind_of(mrb, ruby_field, mrb->string_class)) { mrb_raise(mrb, E_TYPE_ERROR, "String expected"); return mrb_nil_value(); } const char * native_field = mrb_string_value_cstr(mrb, &ruby_field); native_self->name = native_field; return ruby_field; }
/* set_pixel_data * * Parameters: * - value: const char * */ mrb_value mrb_SDL_SDLTestSurfaceImageS_set_pixel_data(mrb_state* mrb, mrb_value self) { struct SDLTest_SurfaceImage_s * native_self = mruby_unbox_SDLTest_SurfaceImage_s(self); mrb_value ruby_field; mrb_get_args(mrb, "o", &ruby_field); /* type checking */ if (!mrb_obj_is_kind_of(mrb, ruby_field, mrb->string_class)) { mrb_raise(mrb, E_TYPE_ERROR, "String expected"); return mrb_nil_value(); } const char * native_field = mrb_string_value_cstr(mrb, &ruby_field); native_self->pixel_data = native_field; return ruby_field; }
int mrb_to_encoding_index(mrb_state *mrb, mrb_value enc) { int idx; idx = enc_check_encoding(mrb, enc); if (idx >= 0) { return idx; } else if (mrb_nil_p(enc = mrb_check_string_type(mrb, enc))) { return -1; } if (!mrb_enc_asciicompat(mrb, mrb_enc_get(mrb, enc))) { return -1; } //return mrb_enc_find_index(StringValueCStr(enc)); return mrb_enc_find_index(mrb, mrb_string_value_cstr(mrb, &enc)); }
mrb_value mrb_io_s_sysopen(mrb_state *mrb, mrb_value klass) { mrb_value path = mrb_nil_value(); mrb_value mode = mrb_nil_value(); mrb_int fd, flags, perm = -1; mrb_get_args(mrb, "S|Si", &path, &mode, &perm); if (mrb_nil_p(mode)) { mode = mrb_str_new_cstr(mrb, "r"); } if (perm < 0) { perm = 0666; } flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); fd = io_open(mrb, path, flags, perm); return mrb_fixnum_value(fd); }
mrb_value mrb_io_initialize(mrb_state *mrb, mrb_value io) { struct mrb_io *fptr; mrb_int fd; mrb_value mode, opt; int flags; mode = opt = mrb_nil_value(); mrb_get_args(mrb, "i|So", &fd, &mode, &opt); if (mrb_nil_p(mode)) { mode = mrb_str_new_cstr(mrb, "r"); } if (mrb_nil_p(opt)) { opt = mrb_hash_new(mrb); } flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0)); fptr = DATA_PTR(io); if (fptr != NULL) { fptr_finalize(mrb, fptr, 0); mrb_free(mrb, fptr); } fptr = mrb_io_alloc(mrb); DATA_TYPE(io) = &mrb_io_type; DATA_PTR(io) = fptr; fptr->fd = fd; fptr->writable = ((flags & FMODE_WRITABLE) != 0); fptr->sync = 0; return io; }
//---------------------------------------------------------- void ScriptEngine::closeOnException() { if (mMrb->exc) { // Kernel.p mrb_p(mMrb, mrb_obj_value(mMrb->exc)); // Save error message & Draw to display mrb_value str = mrb_funcall(mMrb, mrb_obj_value(mMrb->exc), "inspect", 0); mErrorMsg = mrb_string_value_cstr(mMrb, &str); // Insert a line break at the 40 digits each static const int COLUMN = 40; int insertPos = COLUMN; while (mErrorMsg.length() > insertPos) { mErrorMsg.insert(insertPos, "\n"); insertPos += COLUMN + 1; } // Close mrb mErroredMrb = mMrb; mMrb = NULL; } }
mrb_value mrb_io_s_popen(mrb_state *mrb, mrb_value klass) { mrb_value cmd, io; mrb_value mode = mrb_str_new_cstr(mrb, "r"); mrb_value opt = mrb_hash_new(mrb); struct mrb_io *fptr; const char *pname; int pid = 0, flags; STARTUPINFO si; PROCESS_INFORMATION pi; SECURITY_ATTRIBUTES saAttr; HANDLE ifd[2]; HANDLE ofd[2]; int doexec; int opt_in, opt_out, opt_err; ifd[0] = INVALID_HANDLE_VALUE; ifd[1] = INVALID_HANDLE_VALUE; ofd[0] = INVALID_HANDLE_VALUE; ofd[1] = INVALID_HANDLE_VALUE; mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); pname = mrb_string_value_cstr(mrb, &cmd); flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); doexec = (strcmp("-", pname) != 0); opt_in = option_to_fd(mrb, opt, "in"); opt_out = option_to_fd(mrb, opt, "out"); opt_err = option_to_fd(mrb, opt, "err"); saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); saAttr.bInheritHandle = TRUE; saAttr.lpSecurityDescriptor = NULL; if (flags & FMODE_READABLE) { if (!CreatePipe(&ofd[0], &ofd[1], &saAttr, 0) || !SetHandleInformation(ofd[0], HANDLE_FLAG_INHERIT, 0)) { mrb_sys_fail(mrb, "pipe"); } } if (flags & FMODE_WRITABLE) { if (!CreatePipe(&ifd[0], &ifd[1], &saAttr, 0) || !SetHandleInformation(ifd[1], HANDLE_FLAG_INHERIT, 0)) { mrb_sys_fail(mrb, "pipe"); } } if (doexec) { ZeroMemory(&pi, sizeof(pi)); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags |= STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; si.dwFlags |= STARTF_USESTDHANDLES; if (flags & FMODE_READABLE) { si.hStdOutput = ofd[1]; si.hStdError = ofd[1]; } if (flags & FMODE_WRITABLE) { si.hStdInput = ifd[0]; } if (!CreateProcess( NULL, (char*)pname, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP, NULL, NULL, &si, &pi)) { CloseHandle(ifd[0]); CloseHandle(ifd[1]); CloseHandle(ofd[0]); CloseHandle(ofd[1]); mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd); } CloseHandle(pi.hThread); CloseHandle(ifd[0]); CloseHandle(ofd[1]); pid = pi.dwProcessId; } mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); fptr = mrb_io_alloc(mrb); fptr->fd = _open_osfhandle((intptr_t)ofd[0], 0); fptr->fd2 = _open_osfhandle((intptr_t)ifd[1], 0); fptr->pid = pid; fptr->readable = ((flags & FMODE_READABLE) != 0); fptr->writable = ((flags & FMODE_WRITABLE) != 0); fptr->sync = 0; DATA_TYPE(io) = &mrb_io_type; DATA_PTR(io) = fptr; return io; }
mrb_value mrb_io_s_popen(mrb_state *mrb, mrb_value klass) { mrb_value cmd, io, result; mrb_value mode = mrb_str_new_cstr(mrb, "r"); mrb_value opt = mrb_hash_new(mrb); struct mrb_io *fptr; const char *pname; int pid, flags, fd, write_fd = -1; int pr[2] = { -1, -1 }; int pw[2] = { -1, -1 }; int doexec; int saved_errno; mrb_get_args(mrb, "S|SH", &cmd, &mode, &opt); io = mrb_obj_value(mrb_data_object_alloc(mrb, mrb_class_ptr(klass), NULL, &mrb_io_type)); pname = mrb_string_value_cstr(mrb, &cmd); flags = mrb_io_modestr_to_flags(mrb, mrb_string_value_cstr(mrb, &mode)); doexec = (strcmp("-", pname) != 0); if ((flags & FMODE_READABLE) && pipe(pr) == -1) { mrb_sys_fail(mrb, "pipe"); } if ((flags & FMODE_WRITABLE) && pipe(pw) == -1) { if (pr[0] != -1) close(pr[0]); if (pr[1] != -1) close(pr[1]); mrb_sys_fail(mrb, "pipe"); } if (!doexec) { // XXX fflush(stdin); fflush(stdout); fflush(stderr); } result = mrb_nil_value(); switch (pid = fork()) { case 0: /* child */ if (flags & FMODE_READABLE) { close(pr[0]); if (pr[1] != 1) { dup2(pr[1], 1); close(pr[1]); } } if (flags & FMODE_WRITABLE) { close(pw[1]); if (pw[0] != 0) { dup2(pw[0], 0); close(pw[0]); } } if (doexec) { for (fd = 3; fd < NOFILE; fd++) { close(fd); } mrb_proc_exec(pname); mrb_raisef(mrb, E_IO_ERROR, "command not found: %S", cmd); _exit(127); } result = mrb_nil_value(); break; default: /* parent */ if ((flags & FMODE_READABLE) && (flags & FMODE_WRITABLE)) { close(pr[1]); fd = pr[0]; close(pw[0]); write_fd = pw[1]; } else if (flags & FMODE_READABLE) { close(pr[1]); fd = pr[0]; } else { close(pw[0]); fd = pw[1]; } mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@buf"), mrb_str_new_cstr(mrb, "")); mrb_iv_set(mrb, io, mrb_intern_cstr(mrb, "@pos"), mrb_fixnum_value(0)); fptr = mrb_io_alloc(mrb); fptr->fd = fd; fptr->fd2 = write_fd; fptr->pid = pid; fptr->writable = ((flags & FMODE_WRITABLE) != 0); fptr->sync = 0; DATA_TYPE(io) = &mrb_io_type; DATA_PTR(io) = fptr; result = io; break; case -1: /* error */ saved_errno = errno; if (flags & FMODE_READABLE) { close(pr[0]); close(pr[1]); } if (flags & FMODE_WRITABLE) { close(pw[0]); close(pw[1]); } errno = saved_errno; mrb_sys_fail(mrb, "pipe_open failed."); break; } return result; }
static mrb_value mrb_java_support_exec(mrb_state *mrb, mrb_value obj) { mrb_value *argv; mrb_int argc; fflush(stdout); fflush(stderr); mrb_get_args(mrb, "*", &argv, &argc); if (argc < 3) { mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); } // Process the arguments from mruby int java_opts_start = 0; const char *java_dl = mrb_string_value_cstr(mrb, &argv[java_opts_start++]); const char *jli_dl = mrb_string_value_cstr(mrb, &argv[java_opts_start++]); const char *java_main_class = mrb_string_value_cstr(mrb, &argv[java_opts_start++]); const int java_opts_count = mrb_fixnum(argv[java_opts_start++]); const int ruby_opts_start = java_opts_start + java_opts_count; const int ruby_opts_count = argc - ruby_opts_start; const char **java_opts = process_mrb_args(mrb, argv, java_opts_start, java_opts_count); const char **ruby_opts = process_mrb_args(mrb, argv, ruby_opts_start, ruby_opts_count); CreateJavaVM_t* createJavaVM = NULL; #if defined(_WIN32) || defined(_WIN64) HMODULE jvmdll = LoadLibrary(java_dl); if (!jvmdll) { mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot load jvm.dll"); } createJavaVM = (CreateJavaVM_t*) GetProcAddress(jvmdll, "JNI_CreateJavaVM"); #elif defined(__APPLE__) // jli needs to be loaded on OSX because otherwise the OS tries to run the system Java void *libjli = dlopen(jli_dl, RTLD_NOW + RTLD_GLOBAL); void *libjvm = dlopen(java_dl, RTLD_NOW + RTLD_GLOBAL); if (!libjvm) { mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot load libjvm.dylib"); } createJavaVM = (CreateJavaVM_t*) dlsym(libjvm, "JNI_CreateJavaVM"); #else void *libjvm = dlopen(java_dl, RTLD_NOW + RTLD_GLOBAL); if (!libjvm) { mrb_raise(mrb, E_RUNTIME_ERROR, "Cannot load libjvm.so"); } createJavaVM = (CreateJavaVM_t*) dlsym(libjvm, "JNI_CreateJavaVM"); #endif if (createJavaVM == NULL) { mrb_raise(mrb, E_RUNTIME_ERROR, "Could not load JVM"); } else { launch_jvm_in_proc(mrb, createJavaVM, java_main_class, java_opts, java_opts_count, ruby_opts, ruby_opts_count); } #if defined(_WIN32) || defined(_WIN64) FreeLibrary(jvmdll); #elif defined(__APPLE__) dlclose(libjli); dlclose(libjvm); #else dlclose(libjvm); #endif return mrb_true_value(); }
static void mrb_lcd_print_line(mrb_state *mrb, mrb_value lcd, mrb_value *str) { mrb_lcd_t *plcd = (mrb_lcd_t*)DATA_PTR(lcd); const char *src = mrb_string_value_cstr(mrb, str); size_t len = strlen(src); char *buf = mrb_malloc(mrb, len+1); ev3_font_size *f = &_font_size[plcd->font]; mrb_int cw; mrb_int csr = plcd->cx; char *dst; mrb_bool lf; mrb_assert(plcd->font == EV3_FONT_SMALL || plcd->font == EV3_FONT_MEDIUM); mrb_assert(f->w != 0 && f->h != 0); cw = plcd->width / f->w; memset(buf, 0, len+1); dst = buf; while (len--) { lf = FALSE; if (*src == '\n') { lf = TRUE; src++; } else { *dst++ = *src++; csr++; if (csr >= cw) { lf = TRUE; } } if (lf) { *dst = '\0'; ev3_lcd_draw_string( buf, plcd->left + plcd->cx * f->w, plcd->top + plcd->cy * f->h ); /* line feed */ #ifdef EV3 ev3_lcd_fill_rect( plcd->left + csr * f->w, plcd->top + plcd->cy * f->h, plcd->width - csr * f->w, f->h, plcd->color ? 0 : 1 ); #else MRBEV3_PUTS(""); #endif plcd->cy = (plcd->cy + 1) % (plcd->height / f->h); plcd->cx = csr = 0; memset(buf, 0, strlen(src)+1); dst = buf; } } *dst = '\0'; if (dst != buf) { ev3_lcd_draw_string( buf, plcd->left + plcd->cx * f->w, plcd->top + plcd->cy * f->h ); } mrb_free(mrb, buf); /* update cursor */ plcd->cx = csr; }
int main(int argc, char const *argv[]) { #ifdef _MEM_PROFILER uint8_t checkpoint_set = 0; #endif fd_set rfds; char buffer[PIPE_BUFFER_SIZE]; int i, n; Plugin plugins[MAX_PLUGINS]; int plugins_count = 0; mrb_state *mrb; mrb_value r_output, r_plugins_list; mrb_sym output_gv_sym, plugins_to_load_gv_sym; printf("Version: %s\n", PROBE_VERSION); if( argc != 2 ){ printf("Usage: %s <config_path>\n", argv[0]); exit(1); } #ifdef _MEM_PROFILER init_profiler(); #endif config_path = argv[1]; printf("Initializing core...\n"); mrb = mrb_open_allocf(profiler_allocf, "main"); output_gv_sym = mrb_intern_cstr(mrb, "$output"); plugins_to_load_gv_sym = mrb_intern_cstr(mrb, "$plugins_to_load"); setup_api(mrb); execute_file(mrb, "plugins/main.rb"); execute_file(mrb, config_path); printf("Loading plugins...\n"); r_plugins_list = mrb_gv_get(mrb, plugins_to_load_gv_sym); for(i = 0; i< mrb_ary_len(mrb, r_plugins_list); i++){ char *path, tmp[100]; int ssize; mrb_value r_plugin_name = mrb_ary_ref(mrb, r_plugins_list, i); const char *plugin_name = mrb_string_value_cstr(mrb, &r_plugin_name); snprintf(tmp, sizeof(tmp) - 1, "plugins/%s.rb", plugin_name); ssize = strlen(tmp); path = malloc(ssize + 1); strncpy(path, tmp, ssize); path[ssize] = '\0'; if( access(path, F_OK) == -1 ){ printf("cannot open plugin file \"%s\": %s\n", path, strerror(errno)); exit(1); } init_plugin_from_file(&plugins[plugins_count], path, plugin_name); plugins_count++; } printf("Instanciating output class...\n"); r_output = mrb_gv_get(mrb, output_gv_sym); interval = mrb_fixnum(mrb_funcall(mrb, r_output, "interval", 0)); printf("Interval set to %dms\n", (int)interval); printf("Sending initial report...\n"); mrb_funcall(mrb, r_output, "send_report", 0); if (mrb->exc) { mrb_print_error(mrb); exit(1); } // start all the threads for(i= 0; i< plugins_count; i++){ // printf("== plugin %d\n", i); n = pthread_create(&plugins[i].thread, NULL, plugin_thread, (void *)&plugins[i]); if( n < 0 ){ fprintf(stderr, "create failed\n"); } } if( signal(SIGINT, clean_exit) == SIG_ERR){ perror("signal"); exit(1); } while(running){ int fds[MAX_PLUGINS]; int maxfd = 0, ai; struct timeval tv; mrb_value r_buffer; struct timeval cycle_started_at, cycle_completed_at; gettimeofday(&cycle_started_at, NULL); bzero(fds, sizeof(int) * MAX_PLUGINS); // ask every plugin to send their data for(i= 0; i< plugins_count; i++){ strcpy(buffer, "request"); if( send(plugins[i].host_pipe, buffer, strlen(buffer), 0) == -1 ){ printf("send error when writing in pipe connected to plugin '%s'\n", plugins[i].name); } fds[i] = plugins[i].host_pipe; // printf("sent request to %d\n", i); } // printf("waiting answers...\n"); // and now wait for each answer while(1){ int left = 0; FD_ZERO(&rfds); for(i = 0; i< MAX_PLUGINS; i++){ if( fds[i] != NOPLUGIN_VALUE ){ FD_SET(fds[i], &rfds); left++; if( fds[i] > maxfd ) maxfd = fds[i]; } } // printf("left: %d %d\n", left, left <= 0); if( !running || (0 == left) ) break; // substract 20ms to stay below the loop delay fill_timeout(&tv, cycle_started_at, interval - 20); // printf("before select\n"); n = select(maxfd + 1, &rfds, NULL, NULL, &tv); // printf("after select: %d\n", n); if( n > 0 ){ // find out which pipes have data for(i = 0; i< MAX_PLUGINS; i++){ if( (fds[i] != NOPLUGIN_VALUE) && FD_ISSET(fds[i], &rfds) ){ while (1){ struct timeval answered_at; n = read(fds[i], buffer, sizeof(buffer)); if( n == -1 ){ if( errno != EAGAIN ) perror("read"); break; } if( n == PIPE_BUFFER_SIZE ){ printf("PIPE_BUFFER_SIZE is too small, increase it ! (value: %d)\n", PIPE_BUFFER_SIZE); continue; } gettimeofday(&answered_at, NULL); // printf("received answer from %s in %u ms\n", (const char *) plugins[i].mrb->ud, // (uint32_t)((answered_at.tv_sec - cycle_started_at.tv_sec) * 1000 + // (answered_at.tv_usec - cycle_started_at.tv_usec) / 1000) // ); buffer[n] = 0x00; ai = mrb_gc_arena_save(mrb); r_buffer = mrb_str_buf_new(mrb, n); mrb_str_buf_cat(mrb, r_buffer, buffer, n); // mrb_funcall(mrb, r_output, "tick", 0); mrb_funcall(mrb, r_output, "add", 1, r_buffer); check_exception("add", mrb); // pp(mrb, r_output, 0); mrb_gc_arena_restore(mrb, ai); } fds[i] = 0; } } } else if( n == 0 ) { printf("no responses received from %d plugins.\n", left); break; // timeout } else { perror("select"); } } int idx = mrb_gc_arena_save(mrb); mrb_funcall(mrb, r_output, "flush", 0); check_exception("flush", mrb); mrb_gc_arena_restore(mrb, idx); // and now sleep until the next cycle gettimeofday(&cycle_completed_at, NULL); #ifdef _MEM_PROFILER if( checkpoint_set ){ print_allocations(); } #endif // force a gc run at the end of each cycle mrb_full_gc(mrb); // printf("[main] capa: %d / %d\n", mrb->arena_idx, mrb->arena_capa); // for(i= 0; i< plugins_count; i++){ // printf("[%s] capa: %d / %d\n", plugins[i].name, plugins[i].mrb->arena_idx, plugins[i].mrb->arena_capa); // } #ifdef _MEM_PROFILER checkpoint_set = 1; // and set starting point profiler_set_checkpoint(); #endif #ifdef _MEM_PROFILER_RUBY // dump VMS state dump_state(mrb); for(i= 0; i< plugins_count; i++){ dump_state(plugins[i].mrb); } #endif fflush(stdout); sleep_delay(&cycle_started_at, &cycle_completed_at, interval); } printf("Sending exit signal to all plugins...\n"); strcpy(buffer, "exit"); for(i= 0; i< plugins_count; i++){ C_CHECK("send", send(plugins[i].host_pipe, buffer, strlen(buffer), 0) ); } printf("Giving some time for threads to exit...\n\n"); really_sleep(2000); for(i= 0; i< plugins_count; i++){ int ret = pthread_kill(plugins[i].thread, 0); // if a success is returned then the thread is still alive // which means the thread did not acknoledged the exit message // kill it. if( ret == 0 ){ printf(" - plugin \"%s\" failed to exit properly, killing it...\n", (const char *) plugins[i].mrb->ud); pthread_cancel(plugins[i].thread); } else { printf(" - plugin \"%s\" exited properly.\n", (const char *) plugins[i].mrb->allocf_ud); } if( pthread_join(plugins[i].thread, NULL) < 0){ fprintf(stderr, "join failed\n"); } mrb_close(plugins[i].mrb); } mrb_close(mrb); printf("Exited !\n"); return 0; }