[Groonga-commit] groonga/groonga at 6b9c28e [master] Support multiple plugin search directories

Back to archive index

Kouhei Sutou null+****@clear*****
Thu Sep 13 13:04:39 JST 2018


Kouhei Sutou	2018-09-13 13:04:39 +0900 (Thu, 13 Sep 2018)

  Revision: 6b9c28e182f4a18a274a608d48afa312b266b18f
  https://github.com/groonga/groonga/commit/6b9c28e182f4a18a274a608d48afa312b266b18f

  Message:
    Support multiple plugin search directories
    
    You can specify multiple directories to GRN_PLUGINS_PATH separated
    with ":" on non Windows, ";" on Windows.
    
    GRN_PLUGINS_PATH has high priority than the existing GRN_PLUGINS_DIR.
    
    TODO: Windows support

  Modified files:
    lib/plugin.c
    test/command/run-test.sh

  Modified: lib/plugin.c (+179 -84)
===================================================================
--- lib/plugin.c    2018-09-13 13:04:27 +0900 (61198473e)
+++ lib/plugin.c    2018-09-13 13:04:39 +0900 (10fb6589d)
@@ -49,6 +49,24 @@
 static grn_hash *grn_plugins = NULL;
 static grn_critical_section grn_plugins_lock;
 static grn_ctx grn_plugins_ctx;
+static grn_obj grn_plugins_path;
+
+#define GRN_PLUGINS_DIR_EACH_BEGIN(dir, dir_length) do {                \
+  unsigned int i_;                                                      \
+  const unsigned int n_dirs_ = grn_vector_size(&grn_plugins_ctx,        \
+                                               &grn_plugins_path);      \
+  for (i_ = 0; i_ < n_dirs_; i_++) {                                    \
+    const char *dir = NULL;                                             \
+    unsigned int dir_length;                                            \
+    dir_length = grn_vector_get_element(&grn_plugins_ctx,               \
+                                        &grn_plugins_path,              \
+                                        i_,                             \
+                                        &dir,                           \
+                                        NULL,                           \
+                                        NULL);
+#define GRN_PLUGINS_DIR_EACH_END()                                      \
+  }                                                                     \
+} while (GRN_FALSE)
 
 #ifdef HAVE_DLFCN_H
 #  include <dlfcn.h>
@@ -71,13 +89,17 @@ static grn_ctx grn_plugins_ctx;
 
 #define GRN_PLUGIN_KEY_SIZE(filename) (strlen((filename)) + 1)
 
-static char grn_plugins_dir[GRN_ENV_BUFFER_SIZE];
+static char grn_plugins_path_env[GRN_ENV_BUFFER_SIZE];
+static char grn_plugins_dir_env[GRN_ENV_BUFFER_SIZE];
 
 void
 grn_plugin_init_from_env(void)
 {
+  grn_getenv("GRN_PLUGINS_PATH",
+             grn_plugins_path_env,
+             GRN_ENV_BUFFER_SIZE);
   grn_getenv("GRN_PLUGINS_DIR",
-             grn_plugins_dir,
+             grn_plugins_dir_env,
              GRN_ENV_BUFFER_SIZE);
 }
 
@@ -118,8 +140,6 @@ grn_plugin_path(grn_ctx *ctx, grn_id id)
   const char *path;
   grn_plugin *plugin;
   int value_size;
-  const char *system_plugins_dir;
-  size_t system_plugins_dir_size;
 
   if (id == GRN_ID_NIL) {
     return NULL;
@@ -134,18 +154,18 @@ grn_plugin_path(grn_ctx *ctx, grn_id id)
   }
 
   path = plugin->path;
-  system_plugins_dir = grn_plugin_get_system_plugins_dir();
-  system_plugins_dir_size = strlen(system_plugins_dir);
-  if (strncmp(system_plugins_dir, path, system_plugins_dir_size) == 0) {
-    const char *plugin_name = path + system_plugins_dir_size;
-    while (plugin_name[0] == '/') {
-      plugin_name++;
+  GRN_PLUGINS_DIR_EACH_BEGIN(dir, dir_length) {
+    if (strncmp(dir, path, dir_length) == 0) {
+      const char *plugin_name = path + dir_length;
+      while (plugin_name[0] == '/') {
+        plugin_name++;
+      }
+      /* TODO: remove suffix too? */
+      return plugin_name;
     }
-    /* TODO: remove suffix too? */
-    return plugin_name;
-  } else {
-    return path;
-  }
+  } GRN_PLUGINS_DIR_EACH_END();
+
+  return path;
 }
 
 #define GRN_PLUGIN_FUNC_PREFIX "grn_plugin_impl_"
@@ -497,18 +517,112 @@ exit:
   return func;
 }
 
+#ifdef WIN32
+static void
+grn_plugins_init_path(grn_ctx *ctx, grn_obj *path, const char *path_env)
+{
+  /* TODO */
+}
+#else /* WIN32 */
+static void
+grn_plugins_init_path(grn_ctx *ctx, grn_obj *path, const char *path_env)
+{
+  const char separator = ':';
+  const char *start = path_env;
+  const char *current;
+
+  for (current = path_env; current[0]; current++) {
+    if (current[0] == separator) {
+      if (current - start > 0) {
+        grn_vector_add_element(&grn_plugins_ctx,
+                               &grn_plugins_path,
+                               start,
+                               current - start,
+                               0,
+                               GRN_DB_TEXT);
+      }
+      start = current + 1;
+    }
+  }
+
+  if (start[0] && current - start > 0) {
+    grn_vector_add_element(&grn_plugins_ctx,
+                           &grn_plugins_path,
+                           start,
+                           current - start,
+                           0,
+                           GRN_DB_TEXT);
+  }
+}
+#endif /* WIN32 */
+
+#ifdef WIN32
+static char *windows_plugins_dir = NULL;
+static char windows_plugins_dir_buffer[PATH_MAX];
+static const char *
+grn_plugin_get_default_system_plugins_dir(void)
+{
+  if (!windows_plugins_dir) {
+    const char *base_dir;
+    const char *relative_path = GRN_RELATIVE_PLUGINS_DIR;
+    size_t base_dir_length;
+
+    base_dir = grn_windows_base_dir();
+    base_dir_length = strlen(base_dir);
+    grn_strcpy(windows_plugins_dir_buffer, PATH_MAX, base_dir);
+    grn_strcat(windows_plugins_dir_buffer, PATH_MAX, "/");
+    grn_strcat(windows_plugins_dir_buffer, PATH_MAX, relative_path);
+    windows_plugins_dir = windows_plugins_dir_buffer;
+  }
+  return windows_plugins_dir;
+}
+
+#else /* WIN32 */
+static const char *
+grn_plugin_get_default_system_plugins_dir(void)
+{
+  return GRN_PLUGINS_DIR;
+}
+#endif /* WIN32 */
+
+const char *
+grn_plugin_get_system_plugins_dir(void)
+{
+  if (grn_plugins_dir_env[0]) {
+    return grn_plugins_dir_env;
+  } else {
+    return grn_plugin_get_default_system_plugins_dir();
+  }
+}
+
 grn_rc
 grn_plugins_init(void)
 {
   CRITICAL_SECTION_INIT(grn_plugins_lock);
   grn_ctx_init(&grn_plugins_ctx, 0);
+  GRN_TEXT_INIT(&grn_plugins_path, GRN_OBJ_VECTOR);
   grn_plugins = grn_hash_create(&grn_plugins_ctx, NULL,
                                 PATH_MAX, sizeof(grn_plugin *),
                                 GRN_OBJ_KEY_VAR_SIZE);
   if (!grn_plugins) {
+    GRN_OBJ_FIN(&grn_plugins_ctx, &grn_plugins_path);
     grn_ctx_fin(&grn_plugins_ctx);
     return GRN_NO_MEMORY_AVAILABLE;
   }
+  if (grn_plugins_path_env[0]) {
+    grn_plugins_init_path(&grn_plugins_ctx,
+                          &grn_plugins_path,
+                          grn_plugins_path_env);
+  }
+  {
+    const char *system_plugins_dir = grn_plugin_get_system_plugins_dir();
+    grn_vector_add_element(&grn_plugins_ctx,
+                           &grn_plugins_path,
+                           system_plugins_dir,
+                           strlen(system_plugins_dir),
+                           0,
+                           GRN_DB_TEXT);
+  }
   return GRN_SUCCESS;
 }
 
@@ -521,6 +635,7 @@ grn_plugins_fin(void)
     grn_plugin_close(&grn_plugins_ctx, id);
   });
   rc = grn_hash_close(&grn_plugins_ctx, grn_plugins);
+  GRN_OBJ_FIN(&grn_plugins_ctx, &grn_plugins_path);
   grn_ctx_fin(&grn_plugins_ctx);
   CRITICAL_SECTION_FIN(grn_plugins_lock);
   return rc;
@@ -562,45 +677,6 @@ grn_plugin_register_by_path(grn_ctx *ctx, const char *path)
   GRN_API_RETURN(ctx->rc);
 }
 
-#ifdef WIN32
-static char *windows_plugins_dir = NULL;
-static char windows_plugins_dir_buffer[PATH_MAX];
-static const char *
-grn_plugin_get_default_system_plugins_dir(void)
-{
-  if (!windows_plugins_dir) {
-    const char *base_dir;
-    const char *relative_path = GRN_RELATIVE_PLUGINS_DIR;
-    size_t base_dir_length;
-
-    base_dir = grn_windows_base_dir();
-    base_dir_length = strlen(base_dir);
-    grn_strcpy(windows_plugins_dir_buffer, PATH_MAX, base_dir);
-    grn_strcat(windows_plugins_dir_buffer, PATH_MAX, "/");
-    grn_strcat(windows_plugins_dir_buffer, PATH_MAX, relative_path);
-    windows_plugins_dir = windows_plugins_dir_buffer;
-  }
-  return windows_plugins_dir;
-}
-
-#else /* WIN32 */
-static const char *
-grn_plugin_get_default_system_plugins_dir(void)
-{
-  return GRN_PLUGINS_DIR;
-}
-#endif /* WIN32 */
-
-const char *
-grn_plugin_get_system_plugins_dir(void)
-{
-  if (grn_plugins_dir[0]) {
-    return grn_plugins_dir;
-  } else {
-    return grn_plugin_get_default_system_plugins_dir();
-  }
-}
-
 static char *
 grn_plugin_find_path_raw(grn_ctx *ctx, const char *path)
 {
@@ -711,40 +787,12 @@ grn_plugin_find_path_libs_so(grn_ctx *ctx, const char *path, size_t path_len)
   return grn_plugin_find_path_raw(ctx, libs_so_path);
 }
 
-char *
-grn_plugin_find_path(grn_ctx *ctx, const char *name)
+static char *
+grn_plugin_find_path_one(grn_ctx *ctx, const char *path)
 {
-  const char *plugins_dir;
-  char dir_last_char;
-  char path[PATH_MAX];
-  int name_length, max_name_length;
   char *found_path = NULL;
   size_t path_len;
 
-  GRN_API_ENTER;
-  if (name[0] == '/') {
-    path[0] = '\0';
-  } else {
-    plugins_dir = grn_plugin_get_system_plugins_dir();
-    grn_strcpy(path, PATH_MAX, plugins_dir);
-
-    dir_last_char = plugins_dir[strlen(path) - 1];
-    if (dir_last_char != '/') {
-      grn_strcat(path, PATH_MAX, "/");
-    }
-  }
-
-  name_length = strlen(name);
-  max_name_length = PATH_MAX - strlen(path) - 1;
-  if (name_length > max_name_length) {
-    ERR(GRN_INVALID_ARGUMENT,
-        "plugin name is too long: %d (max: %d) <%s%s>",
-        name_length, max_name_length,
-        path, name);
-    goto exit;
-  }
-  grn_strcat(path, PATH_MAX, name);
-
   found_path = grn_plugin_find_path_raw(ctx, path);
   if (found_path) {
     goto exit;
@@ -777,6 +825,53 @@ grn_plugin_find_path(grn_ctx *ctx, const char *name)
   }
 
 exit :
+  return found_path;
+}
+
+char *
+grn_plugin_find_path(grn_ctx *ctx, const char *name)
+{
+  char *found_path = NULL;
+
+  GRN_API_ENTER;
+
+  if (name[0] == '/') {
+    found_path = grn_plugin_find_path_one(ctx, name);
+  } else {
+    GRN_PLUGINS_DIR_EACH_BEGIN(dir, dir_length) {
+      char dir_last_char;
+      char path[PATH_MAX];
+      int name_length, max_name_length;
+
+      grn_strncpy(path, PATH_MAX, dir, dir_length);
+      path[dir_length] = '\0';
+
+      dir_last_char = dir[dir_length - 1];
+      if (dir_last_char != '/') {
+        grn_strcat(path, PATH_MAX, "/");
+      }
+
+      name_length = strlen(name);
+      max_name_length = PATH_MAX - strlen(path) - 1;
+      if (name_length > max_name_length) {
+        ERR(GRN_INVALID_ARGUMENT,
+            "plugin name is too long: %d (max: %d) <%s%s>",
+            name_length, max_name_length,
+            path, name);
+        break;
+      }
+      grn_strcat(path, PATH_MAX, name);
+
+      found_path = grn_plugin_find_path_one(ctx, path);
+      if (found_path) {
+        break;
+      }
+      if (ctx->rc != GRN_SUCCESS) {
+        break;
+      }
+    } GRN_PLUGINS_DIR_EACH_END();
+  }
+
   GRN_API_RETURN(found_path);
 }
 

  Modified: test/command/run-test.sh (+3 -1)
===================================================================
--- test/command/run-test.sh    2018-09-13 13:04:27 +0900 (be981dc2a)
+++ test/command/run-test.sh    2018-09-13 13:04:39 +0900 (e2c0b3f82)
@@ -35,8 +35,10 @@ fi
 
 . "${build_top_dir}/config.sh"
 
-GRN_PLUGINS_DIR="$build_top_dir/plugins"
+GRN_PLUGINS_DIR="$source_top_dir/plugins"
+GRN_PLUGINS_PATH="$build_top_dir/plugins"
 export GRN_PLUGINS_DIR
+export GRN_PLUGINS_PATH
 
 GRN_RUBY_SCRIPTS_DIR="$source_top_dir/lib/mrb/scripts"
 export GRN_RUBY_SCRIPTS_DIR
-------------- next part --------------
HTML����������������������������...
URL: https://lists.osdn.me/mailman/archives/groonga-commit/attachments/20180913/c668a6ac/attachment-0001.htm 



More information about the Groonga-commit mailing list
Back to archive index