shell_plugin.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /*
  2. * shell_plugin.c
  3. */
  4. #include "private.h"
  5. #include <assert.h>
  6. #include <string.h>
  7. #include "lub/string.h"
  8. #include "lub/list.h"
  9. #include "lub/bintree.h"
  10. #include "clish/plugin.h"
  11. #include "clish/view.h"
  12. /*----------------------------------------------------------------------- */
  13. /* For all plugins:
  14. * * dlopen(plugin)
  15. * * dlsym(initialize function)
  16. * * exec init functions to get all plugin syms
  17. */
  18. int clish_shell_load_plugins(clish_shell_t *this)
  19. {
  20. lub_list_node_t *iter;
  21. clish_plugin_t *plugin;
  22. assert(this);
  23. /* Iterate elements */
  24. for(iter = lub_list__get_head(this->plugins);
  25. iter; iter = lub_list_node__get_next(iter)) {
  26. plugin = (clish_plugin_t *)lub_list_node__get_data(iter);
  27. if (!clish_plugin_load(plugin)) {
  28. fprintf(stderr, "Error: Can't load plugin %s.\n",
  29. clish_plugin__get_file(plugin));
  30. return -1;
  31. }
  32. #ifdef DEBUG
  33. clish_plugin_dump(plugin);
  34. #endif
  35. }
  36. return 0;
  37. }
  38. /*----------------------------------------------------------------------- */
  39. /* Find plugin by name. */
  40. static clish_plugin_t *plugin_by_name(clish_shell_t *this, const char *name)
  41. {
  42. lub_list_node_t *iter;
  43. clish_plugin_t *plugin;
  44. /* Iterate elements */
  45. for(iter = lub_list__get_head(this->plugins);
  46. iter; iter = lub_list_node__get_next(iter)) {
  47. plugin = (clish_plugin_t *)lub_list_node__get_data(iter);
  48. if (!strcmp(clish_plugin__get_name(plugin), name))
  49. return plugin;
  50. }
  51. return NULL;
  52. }
  53. /*----------------------------------------------------------------------- */
  54. /* Iterate plugins to find symbol by name.
  55. * The symbol name can be simple or with namespace:
  56. * mysym@plugin1
  57. * The symbols with prefix will be resolved using specified plugin only.
  58. */
  59. static clish_plugin_fn_t *plugins_find_sym(clish_shell_t *this, const char *name)
  60. {
  61. lub_list_node_t *iter;
  62. clish_plugin_t *plugin;
  63. clish_plugin_fn_t *func = NULL;
  64. /* To parse command name */
  65. char *saveptr;
  66. const char *delim = "@";
  67. char *plugin_name = NULL;
  68. char *cmdn = NULL;
  69. char *str = lub_string_dup(name);
  70. assert(this);
  71. /* Parse name to get sym name and optional plugin name */
  72. cmdn = strtok_r(str, delim, &saveptr);
  73. if (!cmdn)
  74. goto end;
  75. plugin_name = strtok_r(NULL, delim, &saveptr);
  76. if (plugin_name) {
  77. /* Search for symbol in specified plugin */
  78. plugin = plugin_by_name(this, plugin_name);
  79. if (!plugin)
  80. goto end;
  81. func = clish_plugin_get_sym(plugin, cmdn);
  82. } else {
  83. /* Iterate all plugins */
  84. for(iter = lub_list__get_head(this->plugins);
  85. iter; iter = lub_list_node__get_next(iter)) {
  86. plugin = (clish_plugin_t *)lub_list_node__get_data(iter);
  87. if ((func = clish_plugin_get_sym(plugin, cmdn)))
  88. break;
  89. }
  90. }
  91. end:
  92. lub_string_free(str);
  93. return func;
  94. }
  95. /*----------------------------------------------------------------------- */
  96. static int plugins_link_view(clish_shell_t *this, clish_view_t *view)
  97. {
  98. clish_command_t *c;
  99. lub_bintree_iterator_t iter;
  100. lub_bintree_t *tree;
  101. tree = clish_view__cmd_tree(view);
  102. /* Iterate the tree of commands */
  103. c = lub_bintree_findfirst(tree);
  104. for (lub_bintree_iterator_init(&iter, tree, c);
  105. c; c = lub_bintree_iterator_next(&iter)) {
  106. plugins_find_sym(this, "jjj");
  107. printf("command: %s\n", clish_command__get_name(c));
  108. }
  109. return 0;
  110. }
  111. /*----------------------------------------------------------------------- */
  112. int clish_shell_link_plugins(clish_shell_t *this)
  113. {
  114. clish_view_t *v;
  115. lub_bintree_iterator_t iter;
  116. v = lub_bintree_findfirst(&this->view_tree);
  117. /* Iterate the tree of views */
  118. for (lub_bintree_iterator_init(&iter, &this->view_tree, v);
  119. v; v = lub_bintree_iterator_next(&iter)) {
  120. if (plugins_link_view(this, v))
  121. return -1;
  122. }
  123. return 0;
  124. }