kaction.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <assert.h>
  5. #include <faux/str.h>
  6. #include <faux/conv.h>
  7. #include <faux/list.h>
  8. #include <klish/khelper.h>
  9. #include <klish/kaction.h>
  10. struct kaction_s {
  11. char *sym_ref; // Text reference to symbol
  12. char *lock; // Named lock
  13. bool_t interrupt;
  14. bool_t interactive;
  15. kaction_cond_e exec_on;
  16. bool_t update_retcode;
  17. char *script;
  18. //ksym_t *sym; // Symbol
  19. };
  20. // Simple methods
  21. // Sym reference (must be resolved later)
  22. KGET_STR(action, sym_ref);
  23. KSET_STR_ONCE(action, sym_ref);
  24. // Lock
  25. KGET_STR(action, lock);
  26. KSET_STR(action, lock);
  27. // Interrupt
  28. KGET_BOOL(action, interrupt);
  29. KSET_BOOL(action, interrupt);
  30. // Interactive
  31. KGET_BOOL(action, interactive);
  32. KSET_BOOL(action, interactive);
  33. // Exec_on
  34. KGET(action, kaction_cond_e, exec_on);
  35. KSET(action, kaction_cond_e, exec_on);
  36. // Update_retcode
  37. KGET_BOOL(action, update_retcode);
  38. KSET_BOOL(action, update_retcode);
  39. // Script
  40. KGET_STR(action, script);
  41. KSET_STR(action, script);
  42. static kaction_t *kaction_new_empty(void)
  43. {
  44. kaction_t *action = NULL;
  45. action = faux_zmalloc(sizeof(*action));
  46. assert(action);
  47. if (!action)
  48. return NULL;
  49. // Initialize
  50. action->sym_ref = NULL;
  51. action->lock = NULL;
  52. action->interrupt = BOOL_FALSE;
  53. action->interactive = BOOL_FALSE;
  54. action->exec_on = KACTION_COND_SUCCESS;
  55. action->update_retcode = BOOL_TRUE;
  56. action->script = NULL;
  57. return action;
  58. }
  59. kaction_t *kaction_new(const iaction_t *info, kaction_error_e *error)
  60. {
  61. kaction_t *action = NULL;
  62. action = kaction_new_empty();
  63. assert(action);
  64. if (!action) {
  65. if (error)
  66. *error = KACTION_ERROR_ALLOC;
  67. return NULL;
  68. }
  69. if (!info)
  70. return action;
  71. if (!kaction_parse(action, info, error)) {
  72. kaction_free(action);
  73. return NULL;
  74. }
  75. return action;
  76. }
  77. void kaction_free(kaction_t *action)
  78. {
  79. if (!action)
  80. return;
  81. faux_str_free(action->sym_ref);
  82. faux_str_free(action->lock);
  83. faux_str_free(action->script);
  84. faux_free(action);
  85. }
  86. const char *kaction_strerror(kaction_error_e error)
  87. {
  88. const char *str = NULL;
  89. switch (error) {
  90. case KACTION_ERROR_OK:
  91. str = "Ok";
  92. break;
  93. case KACTION_ERROR_INTERNAL:
  94. str = "Internal error";
  95. break;
  96. case KACTION_ERROR_ALLOC:
  97. str = "Memory allocation error";
  98. break;
  99. case KACTION_ERROR_ATTR_SYM:
  100. str = "Illegal 'sym' attribute";
  101. break;
  102. case KACTION_ERROR_ATTR_LOCK:
  103. str = "Illegal 'lock' attribute";
  104. break;
  105. case KACTION_ERROR_ATTR_INTERRUPT:
  106. str = "Illegal 'interrupt' attribute";
  107. break;
  108. case KACTION_ERROR_ATTR_INTERACTIVE:
  109. str = "Illegal 'interactive' attribute";
  110. break;
  111. case KACTION_ERROR_ATTR_UPDATE_RETCODE:
  112. str = "Illegal 'update_retcode' attribute";
  113. break;
  114. case KACTION_ERROR_ATTR_SCRIPT:
  115. str = "Illegal script";
  116. break;
  117. default:
  118. str = "Unknown error";
  119. break;
  120. }
  121. return str;
  122. }
  123. bool_t kaction_parse(kaction_t *action, const iaction_t *info, kaction_error_e *error)
  124. {
  125. // Sym
  126. if (!faux_str_is_empty(info->sym)) {
  127. if (!kaction_set_sym_ref(action, info->sym)) {
  128. if (error)
  129. *error = KACTION_ERROR_ATTR_SYM;
  130. return BOOL_FALSE;
  131. }
  132. }
  133. // Lock
  134. if (!faux_str_is_empty(info->lock)) {
  135. if (!kaction_set_lock(action, info->lock)) {
  136. if (error)
  137. *error = KACTION_ERROR_ATTR_LOCK;
  138. return BOOL_FALSE;
  139. }
  140. }
  141. // Interrupt
  142. if (!faux_str_is_empty(info->interrupt)) {
  143. bool_t b = BOOL_FALSE;
  144. if (!faux_conv_str2bool(info->interrupt, &b) ||
  145. !kaction_set_interrupt(action, b)) {
  146. if (error)
  147. *error = KACTION_ERROR_ATTR_INTERRUPT;
  148. return BOOL_FALSE;
  149. }
  150. }
  151. // Interactive
  152. if (!faux_str_is_empty(info->interactive)) {
  153. bool_t b = BOOL_FALSE;
  154. if (!faux_conv_str2bool(info->interactive, &b) ||
  155. !kaction_set_interactive(action, b)) {
  156. if (error)
  157. *error = KACTION_ERROR_ATTR_INTERACTIVE;
  158. return BOOL_FALSE;
  159. }
  160. }
  161. // Exec_on
  162. if (!faux_str_is_empty(info->exec_on)) {
  163. kaction_cond_e c = KACTION_COND_SUCCESS;
  164. if (faux_str_casecmp(info->exec_on, "fail"))
  165. c = KACTION_COND_FAIL;
  166. else if (faux_str_casecmp(info->exec_on, "success"))
  167. c = KACTION_COND_SUCCESS;
  168. else if (faux_str_casecmp(info->exec_on, "always"))
  169. c = KACTION_COND_ALWAYS;
  170. else {
  171. if (error)
  172. *error = KACTION_ERROR_ATTR_EXEC_ON;
  173. return BOOL_FALSE;
  174. }
  175. if (!kaction_set_exec_on(action, c)) {
  176. if (error)
  177. *error = KACTION_ERROR_ATTR_EXEC_ON;
  178. return BOOL_FALSE;
  179. }
  180. }
  181. // Update_retcode
  182. if (!faux_str_is_empty(info->update_retcode)) {
  183. bool_t b = BOOL_FALSE;
  184. if (!faux_conv_str2bool(info->update_retcode, &b) ||
  185. !kaction_set_update_retcode(action, b)) {
  186. if (error)
  187. *error = KACTION_ERROR_ATTR_UPDATE_RETCODE;
  188. return BOOL_FALSE;
  189. }
  190. }
  191. // Script
  192. if (!faux_str_is_empty(info->script)) {
  193. if (!kaction_set_script(action, info->script)) {
  194. if (error)
  195. *error = KACTION_ERROR_ATTR_SCRIPT;
  196. return BOOL_FALSE;
  197. }
  198. }
  199. return BOOL_TRUE;
  200. }
  201. kaction_t *kaction_from_iaction(iaction_t *iaction, faux_error_t *error_stack)
  202. {
  203. kaction_t *kaction = NULL;
  204. kaction_error_e kaction_error = KACTION_ERROR_OK;
  205. kaction = kaction_new(iaction, &kaction_error);
  206. if (!kaction) {
  207. faux_error_sprintf(error_stack, "ACTION : %s",
  208. kaction_strerror(kaction_error));
  209. return NULL;
  210. }
  211. return kaction;
  212. }