kplugin.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <stdint.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <faux/str.h>
  7. #include <faux/list.h>
  8. #include <faux/conv.h>
  9. #include <faux/error.h>
  10. #include <klish/khelper.h>
  11. #include <klish/kplugin.h>
  12. #include <klish/ksym.h>
  13. struct kplugin_s {
  14. char *name;
  15. char *id;
  16. char *file;
  17. bool_t global;
  18. char *conf;
  19. uint8_t major;
  20. uint8_t minor;
  21. faux_list_t *syms;
  22. };
  23. // Simple methods
  24. // Name
  25. KGET_STR(plugin, name);
  26. KSET_STR_ONCE(plugin, name);
  27. // ID
  28. KGET_STR(plugin, id);
  29. KSET_STR(plugin, id);
  30. // File
  31. KGET_STR(plugin, file);
  32. KSET_STR(plugin, file);
  33. // Global
  34. KGET_BOOL(plugin, global);
  35. KSET_BOOL(plugin, global);
  36. // Conf
  37. KGET_STR(plugin, conf);
  38. KSET_STR(plugin, conf);
  39. // Version major number
  40. KGET(plugin, uint8_t, major);
  41. KSET(plugin, uint8_t, major);
  42. // Version minor number
  43. KGET(plugin, uint8_t, minor);
  44. KSET(plugin, uint8_t, minor);
  45. // COMMAND list
  46. static KCMP_NESTED(plugin, sym, name);
  47. static KCMP_NESTED_BY_KEY(plugin, sym, name);
  48. KADD_NESTED(plugin, sym);
  49. KFIND_NESTED(plugin, sym);
  50. static kplugin_t *kplugin_new_empty(void)
  51. {
  52. kplugin_t *plugin = NULL;
  53. plugin = faux_zmalloc(sizeof(*plugin));
  54. assert(plugin);
  55. if (!plugin)
  56. return NULL;
  57. // Initialize
  58. plugin->name = NULL;
  59. plugin->id = NULL;
  60. plugin->file = NULL;
  61. plugin->global = BOOL_FALSE;
  62. plugin->conf = NULL;
  63. plugin->major = 0;
  64. plugin->minor = 0;
  65. // SYM list
  66. plugin->syms = faux_list_new(FAUX_LIST_SORTED, FAUX_LIST_UNIQUE,
  67. kplugin_sym_compare, kplugin_sym_kcompare,
  68. (void (*)(void *))ksym_free);
  69. assert(plugin->syms);
  70. return plugin;
  71. }
  72. kplugin_t *kplugin_new(const iplugin_t *info, kplugin_error_e *error)
  73. {
  74. kplugin_t *plugin = NULL;
  75. plugin = kplugin_new_empty();
  76. assert(plugin);
  77. if (!plugin) {
  78. if (error)
  79. *error = KPLUGIN_ERROR_ALLOC;
  80. return NULL;
  81. }
  82. if (!info)
  83. return plugin;
  84. if (!kplugin_parse(plugin, info, error)) {
  85. kplugin_free(plugin);
  86. return NULL;
  87. }
  88. return plugin;
  89. }
  90. void kplugin_free(kplugin_t *plugin)
  91. {
  92. if (!plugin)
  93. return;
  94. faux_str_free(plugin->name);
  95. faux_str_free(plugin->id);
  96. faux_str_free(plugin->file);
  97. faux_str_free(plugin->conf);
  98. faux_list_free(plugin->syms);
  99. faux_free(plugin);
  100. }
  101. const char *kplugin_strerror(kplugin_error_e error)
  102. {
  103. const char *str = NULL;
  104. switch (error) {
  105. case KPLUGIN_ERROR_OK:
  106. str = "Ok";
  107. break;
  108. case KPLUGIN_ERROR_INTERNAL:
  109. str = "Internal error";
  110. break;
  111. case KPLUGIN_ERROR_ALLOC:
  112. str = "Memory allocation error";
  113. break;
  114. case KPLUGIN_ERROR_ATTR_NAME:
  115. str = "Illegal 'name' attribute";
  116. break;
  117. case KPLUGIN_ERROR_ATTR_ID:
  118. str = "Illegal 'id' attribute";
  119. break;
  120. case KPLUGIN_ERROR_ATTR_FILE:
  121. str = "Illegal 'file' attribute";
  122. break;
  123. case KPLUGIN_ERROR_ATTR_GLOBAL:
  124. str = "Illegal 'global' attribute";
  125. break;
  126. case KPLUGIN_ERROR_ATTR_CONF:
  127. str = "Illegal conf";
  128. break;
  129. default:
  130. str = "Unknown error";
  131. break;
  132. }
  133. return str;
  134. }
  135. bool_t kplugin_parse(kplugin_t *plugin, const iplugin_t *info, kplugin_error_e *error)
  136. {
  137. // Name [mandatory]
  138. if (faux_str_is_empty(info->name)) {
  139. if (error)
  140. *error = KPLUGIN_ERROR_ATTR_NAME;
  141. return BOOL_FALSE;
  142. } else {
  143. if (!kplugin_set_name(plugin, info->name)) {
  144. if (error)
  145. *error = KPLUGIN_ERROR_ATTR_NAME;
  146. return BOOL_FALSE;
  147. }
  148. }
  149. // ID
  150. if (!faux_str_is_empty(info->id)) {
  151. if (!kplugin_set_id(plugin, info->id)) {
  152. if (error)
  153. *error = KPLUGIN_ERROR_ATTR_ID;
  154. return BOOL_FALSE;
  155. }
  156. }
  157. // File
  158. if (!faux_str_is_empty(info->file)) {
  159. if (!kplugin_set_file(plugin, info->file)) {
  160. if (error)
  161. *error = KPLUGIN_ERROR_ATTR_FILE;
  162. return BOOL_FALSE;
  163. }
  164. }
  165. // Global
  166. if (!faux_str_is_empty(info->global)) {
  167. bool_t b = BOOL_FALSE;
  168. if (!faux_conv_str2bool(info->global, &b) ||
  169. !kplugin_set_global(plugin, b)) {
  170. if (error)
  171. *error = KPLUGIN_ERROR_ATTR_GLOBAL;
  172. return BOOL_FALSE;
  173. }
  174. }
  175. // Conf
  176. if (!faux_str_is_empty(info->conf)) {
  177. if (!kplugin_set_conf(plugin, info->conf)) {
  178. if (error)
  179. *error = KPLUGIN_ERROR_ATTR_CONF;
  180. return BOOL_FALSE;
  181. }
  182. }
  183. return BOOL_TRUE;
  184. }
  185. kplugin_t *kplugin_from_iplugin(iplugin_t *iplugin, faux_error_t *error_stack)
  186. {
  187. kplugin_t *kplugin = NULL;
  188. kplugin_error_e kplugin_error = KPLUGIN_ERROR_OK;
  189. kplugin = kplugin_new(iplugin, &kplugin_error);
  190. if (!kplugin) {
  191. faux_error_sprintf(error_stack, "PLUGIN \"%s\": %s",
  192. iplugin->name ? iplugin->name : "(null)",
  193. kplugin_strerror(kplugin_error));
  194. return NULL;
  195. }
  196. return kplugin;
  197. }