Kouhei Sutou
null+****@clear*****
Sat Sep 21 00:53:37 JST 2013
Kouhei Sutou 2013-09-21 00:53:37 +0900 (Sat, 21 Sep 2013) New Revision: 55f49ff0912901bd1a94942e90de5193689fa95f https://github.com/groonga/groonga/commit/55f49ff0912901bd1a94942e90de5193689fa95f Message: Add "ruby" command by ruby/ruby plugin It evaluates Ruby expression and returns evaludated value. It is very experimental feature. The API will be changed! Added files: plugins/ruby/Makefile.am plugins/ruby/ruby.c plugins/ruby/sources.am test/command/suite/ruby/eval/numeric.expected test/command/suite/ruby/eval/numeric.test Copied files: plugins/ruby/CMakeLists.txt (from plugins/CMakeLists.txt) Modified files: configure.ac lib/mrb.c lib/mrb.h plugins/CMakeLists.txt plugins/Makefile.am Modified: configure.ac (+4 -0) =================================================================== --- configure.ac 2013-09-20 21:47:30 +0900 (414c801) +++ configure.ac 2013-09-21 00:53:37 +0900 (8ce1601) @@ -227,6 +227,7 @@ AC_CONFIG_FILES([ plugins/suggest/Makefile plugins/table/Makefile plugins/query_expanders/Makefile + plugins/ruby/Makefile examples/Makefile examples/dictionary/Makefile examples/dictionary/edict/Makefile @@ -1179,6 +1180,9 @@ AC_SUBST(suggest_pluginsdir) table_pluginsdir="\${pluginsdir}/table" AC_SUBST(table_pluginsdir) +ruby_pluginsdir="\${pluginsdir}/ruby" +AC_SUBST(ruby_pluginsdir) + AC_MSG_CHECKING(for the suffix of plugin shared libraries) shrext_cmds=$(./libtool --config | grep '^shrext_cmds=') eval $shrext_cmds Modified: lib/mrb.c (+43 -0) =================================================================== --- lib/mrb.c 2013-09-20 21:47:30 +0900 (0797b0e) +++ lib/mrb.c 2013-09-21 00:53:37 +0900 (f90d5cd) @@ -45,6 +45,49 @@ grn_ctx_impl_mrb_fin(grn_ctx *ctx) ctx->impl->mrb = NULL; } } + +mrb_value +grn_mrb_eval(grn_ctx *ctx, const char *script, int script_length) +{ + mrb_state *mrb = ctx->impl->mrb; + int n; + mrb_value result; + struct mrb_parser_state *parser; + + if (!mrb) { + return mrb_nil_value(); + } + + if (script_length < 0) { + script_length = strlen(script); + } + parser = mrb_parse_nstring(mrb, script, script_length, NULL); + n = mrb_generate_code(mrb, parser); + result = mrb_run(mrb, + mrb_proc_new(mrb, mrb->irep[n]), + mrb_top_self(mrb)); + mrb_parser_free(parser); + + return result; +} + +grn_rc +grn_mrb_to_grn(grn_ctx *ctx, mrb_value mrb_object, grn_obj *grn_object) +{ + grn_rc rc = GRN_SUCCESS; + + switch (mrb_type(mrb_object)) { + case MRB_TT_FIXNUM : + grn_obj_reinit(ctx, grn_object, GRN_DB_INT32, 0); + GRN_INT32_SET(ctx, grn_object, mrb_fixnum(mrb_object)); + break; + default : + rc = GRN_INVALID_ARGUMENT; + break; + } + + return rc; +} #else void grn_ctx_impl_mrb_init(grn_ctx *ctx) Modified: lib/mrb.h (+9 -0) =================================================================== --- lib/mrb.h 2013-09-20 21:47:30 +0900 (800aab6) +++ lib/mrb.h 2013-09-21 00:53:37 +0900 (e79944b) @@ -22,6 +22,10 @@ #include "groonga_in.h" #include "ctx.h" +#ifdef GRN_WITH_MRUBY +# include <mruby.h> +#endif + #ifdef __cplusplus extern "C" { #endif @@ -29,6 +33,11 @@ extern "C" { void grn_ctx_impl_mrb_init(grn_ctx *ctx); void grn_ctx_impl_mrb_fin(grn_ctx *ctx); +#ifdef GRN_WITH_MRUBY +mrb_value grn_mrb_eval(grn_ctx *ctx, const char *script, int script_length); +grn_rc grn_mrb_to_grn(grn_ctx *ctx, mrb_value mrb_object, grn_obj *grn_object); +#endif + #ifdef __cplusplus } #endif Modified: plugins/CMakeLists.txt (+1 -0) =================================================================== --- plugins/CMakeLists.txt 2013-09-20 21:47:30 +0900 (9d94824) +++ plugins/CMakeLists.txt 2013-09-21 00:53:37 +0900 (a2a8f28) @@ -17,3 +17,4 @@ add_subdirectory(suggest) add_subdirectory(tokenizers) add_subdirectory(table) add_subdirectory(query_expanders) +add_subdirectory(ruby) Modified: plugins/Makefile.am (+2 -1) =================================================================== --- plugins/Makefile.am 2013-09-20 21:47:30 +0900 (fbe6f15) +++ plugins/Makefile.am 2013-09-21 00:53:37 +0900 (75a0059) @@ -2,7 +2,8 @@ SUBDIRS = \ tokenizers \ suggest \ table \ - query_expanders + query_expanders \ + ruby EXTRA_DIST = \ CMakeLists.txt Copied: plugins/ruby/CMakeLists.txt (+13 -5) 59% =================================================================== --- plugins/CMakeLists.txt 2013-09-20 21:47:30 +0900 (9d94824) +++ plugins/ruby/CMakeLists.txt 2013-09-21 00:53:37 +0900 (5c9dc7b) @@ -1,4 +1,4 @@ -# Copyright(C) 2012 Brazil +# Copyright(C) 2013 Brazil # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public @@ -13,7 +13,15 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -add_subdirectory(suggest) -add_subdirectory(tokenizers) -add_subdirectory(table) -add_subdirectory(query_expanders) +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../../lib + ) + +read_file_list(${CMAKE_CURRENT_SOURCE_DIR}/sources.am RUBY_SOURCES) +add_library(ruby MODULE ${RUBY_SOURCES}) +set_source_files_properties(${RUBY_SOURCES} + PROPERTIES + COMPILE_FLAGS "${GRN_C_COMPILE_FLAGS}") +set_target_properties(ruby PROPERTIES PREFIX "") +target_link_libraries(ruby libgroonga) +install(TARGETS ruby DESTINATION "${GRN_RELATIVE_PLUGINS_DIR}/ruby") Added: plugins/ruby/Makefile.am (+26 -0) 100644 =================================================================== --- /dev/null +++ plugins/ruby/Makefile.am 2013-09-21 00:53:37 +0900 (ea7476d) @@ -0,0 +1,26 @@ +EXTRA_DIST = \ + CMakeLists.txt + +AM_CFLAGS = \ + $(MESSAGE_PACK_CFLAGS) \ + $(MRUBY_CFLAGS) + +AM_CPPFLAGS = \ + -I$(top_builddir) \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/lib + +AM_LDFLAGS = \ + -avoid-version \ + -module \ + -no-undefined + +LIBS = \ + $(top_builddir)/lib/libgroonga.la \ + $(MESSAGE_PACK_LIBS) + +if WITH_MRUBY +ruby_plugins_LTLIBRARIES = ruby.la +endif + +include sources.am Added: plugins/ruby/ruby.c (+107 -0) 100644 =================================================================== --- /dev/null +++ plugins/ruby/ruby.c 2013-09-21 00:53:37 +0900 (3797e3d) @@ -0,0 +1,107 @@ +/* -*- c-basic-offset: 2; indent-tabs-mode: nil -*- */ +/* + Copyright(C) 2013 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include <mrb.h> +#include <output.h> +#include <db.h> +#include <util.h> + +#include <groonga/plugin.h> + +#define VAR GRN_PROC_GET_VAR_BY_OFFSET + +static void +output_result(grn_ctx *ctx, mrb_value result) +{ + grn_obj grn_result; + + GRN_OUTPUT_MAP_OPEN("result", 1); + GRN_OUTPUT_CSTR("value"); + GRN_VOID_INIT(&grn_result); + if (grn_mrb_to_grn(ctx, result, &grn_result) == GRN_SUCCESS) { + GRN_OUTPUT_OBJ(&grn_result, NULL); + } else { + GRN_OUTPUT_CSTR("unsupported return value"); + } + grn_obj_unlink(ctx, &grn_result); + GRN_OUTPUT_MAP_CLOSE(); +} + +static grn_obj * +command_ruby(grn_ctx *ctx, int nargs, grn_obj **args, grn_user_data *user_data) +{ + grn_obj *script; + mrb_value result; + + script = VAR(0); + switch (script->header.domain) { + case GRN_DB_SHORT_TEXT : + case GRN_DB_TEXT : + case GRN_DB_LONG_TEXT : + break; + default : + { + grn_obj inspected; + GRN_TEXT_INIT(&inspected, 0); + grn_inspect(ctx, &inspected, script); + ERR(GRN_INVALID_ARGUMENT, "script must be a string: <%.*s>", + (int)GRN_TEXT_LEN(&inspected), GRN_TEXT_VALUE(&inspected)); + GRN_OBJ_FIN(ctx, &inspected); + return NULL; + } + break; + } + + result = grn_mrb_eval(ctx, GRN_TEXT_VALUE(script), GRN_TEXT_LEN(script)); + output_result(ctx, result); + + return NULL; +} + +grn_rc +GRN_PLUGIN_INIT(grn_ctx *ctx) +{ + return GRN_SUCCESS; +} + +#define DEF_VAR(v,x) do {\ + (v).name = (x);\ + (v).name_size = (x) ? sizeof(x) - 1 : 0;\ + GRN_TEXT_INIT(&(v).value, 0);\ +} while (0) + +#define DEF_COMMAND(name, func, nvars, vars)\ + (grn_proc_create(ctx, (name), (sizeof(name) - 1),\ + GRN_PROC_COMMAND, (func), NULL, NULL, (nvars), (vars))) + +grn_rc +GRN_PLUGIN_REGISTER(grn_ctx *ctx) +{ + grn_expr_var vars[1]; + + DEF_VAR(vars[0], "script"); + DEF_COMMAND("ruby", command_ruby, 1, vars); + + return ctx->rc; +} + +grn_rc +GRN_PLUGIN_FIN(grn_ctx *ctx) +{ + return GRN_SUCCESS; +} Added: plugins/ruby/sources.am (+2 -0) 100644 =================================================================== --- /dev/null +++ plugins/ruby/sources.am 2013-09-21 00:53:37 +0900 (5d8e19a) @@ -0,0 +1,2 @@ +ruby_la_SOURCES = \ + ruby.c Added: test/command/suite/ruby/eval/numeric.expected (+4 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/ruby/eval/numeric.expected 2013-09-21 00:53:37 +0900 (3d34b99) @@ -0,0 +1,4 @@ +register ruby/ruby +[[0,0.0,0.0],true] +ruby "1" +[[0,0.0,0.0],{"value":1}] Added: test/command/suite/ruby/eval/numeric.test (+2 -0) 100644 =================================================================== --- /dev/null +++ test/command/suite/ruby/eval/numeric.test 2013-09-21 00:53:37 +0900 (aeabcf2) @@ -0,0 +1,2 @@ +register ruby/ruby +ruby "1" -------------- next part -------------- HTML����������������������������...Download