logical.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /**
  2. * @file logical.c
  3. * @author Ambroz Bizjak <ambrop7@gmail.com>
  4. *
  5. * @section LICENSE
  6. *
  7. * This file is part of BadVPN.
  8. *
  9. * BadVPN is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2
  11. * as published by the Free Software Foundation.
  12. *
  13. * BadVPN is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License along
  19. * with this program; if not, write to the Free Software Foundation, Inc.,
  20. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  21. *
  22. * @section DESCRIPTION
  23. *
  24. * Module for logical operators.
  25. *
  26. * Synopsis: not(string val)
  27. * Variables:
  28. * string (empty) - "true" if val does not equal "true", "false" otherwise
  29. *
  30. * Synopsis: or(string val1, string val2)
  31. * Variables:
  32. * string (empty) - "true" if val1 or val2 equal "true", "false" otherwise
  33. *
  34. * Synopsis: and(string val1, string val2)
  35. * Variables:
  36. * string (empty) - "true" if val1 and val2 equal "true", "false" otherwise
  37. */
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <ncd/NCDModule.h>
  41. #include <generated/blog_channel_ncd_logical.h>
  42. #define ModuleLog(i, ...) NCDModuleInst_Backend_Log((i), BLOG_CURRENT_CHANNEL, __VA_ARGS__)
  43. struct instance {
  44. NCDModuleInst *i;
  45. int value;
  46. };
  47. static void func_new (NCDModuleInst *i, int not, int or)
  48. {
  49. // allocate instance
  50. struct instance *o = malloc(sizeof(*o));
  51. if (!o) {
  52. ModuleLog(i, BLOG_ERROR, "failed to allocate instance");
  53. goto fail0;
  54. }
  55. NCDModuleInst_Backend_SetUser(i, o);
  56. // init arguments
  57. o->i = i;
  58. // compute value from arguments
  59. if (not) {
  60. NCDValue *arg;
  61. if (!NCDValue_ListRead(o->i->args, 1, &arg)) {
  62. ModuleLog(o->i, BLOG_ERROR, "wrong arity");
  63. goto fail1;
  64. }
  65. if (NCDValue_Type(arg) != NCDVALUE_STRING) {
  66. ModuleLog(o->i, BLOG_ERROR, "wrong type");
  67. goto fail1;
  68. }
  69. o->value = !!strcmp(NCDValue_StringValue(arg), "true");
  70. } else {
  71. NCDValue *arg1;
  72. NCDValue *arg2;
  73. if (!NCDValue_ListRead(o->i->args, 2, &arg1, &arg2)) {
  74. ModuleLog(o->i, BLOG_ERROR, "wrong arity");
  75. goto fail1;
  76. }
  77. if (NCDValue_Type(arg1) != NCDVALUE_STRING || NCDValue_Type(arg2) != NCDVALUE_STRING) {
  78. ModuleLog(o->i, BLOG_ERROR, "wrong type");
  79. goto fail1;
  80. }
  81. if (or) {
  82. o->value = (!strcmp(NCDValue_StringValue(arg1), "true") || !strcmp(NCDValue_StringValue(arg2), "true"));
  83. } else {
  84. o->value = (!strcmp(NCDValue_StringValue(arg1), "true") && !strcmp(NCDValue_StringValue(arg2), "true"));
  85. }
  86. }
  87. // signal up
  88. NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
  89. return;
  90. fail1:
  91. free(o);
  92. fail0:
  93. NCDModuleInst_Backend_SetError(i);
  94. NCDModuleInst_Backend_Event(i, NCDMODULE_EVENT_DEAD);
  95. }
  96. static void func_new_not (NCDModuleInst *i)
  97. {
  98. func_new(i, 1, 0);
  99. }
  100. static void func_new_or (NCDModuleInst *i)
  101. {
  102. func_new(i, 0, 1);
  103. }
  104. static void func_new_and (NCDModuleInst *i)
  105. {
  106. func_new(i, 0, 0);
  107. }
  108. static void func_die (void *vo)
  109. {
  110. struct instance *o = vo;
  111. NCDModuleInst *i = o->i;
  112. // free instance
  113. free(o);
  114. NCDModuleInst_Backend_Event(i, NCDMODULE_EVENT_DEAD);
  115. }
  116. static int func_getvar (void *vo, const char *name, NCDValue *out)
  117. {
  118. struct instance *o = vo;
  119. if (!strcmp(name, "")) {
  120. const char *v = (o->value ? "true" : "false");
  121. if (!NCDValue_InitString(out, v)) {
  122. ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitString failed");
  123. return 0;
  124. }
  125. return 1;
  126. }
  127. return 0;
  128. }
  129. static const struct NCDModule modules[] = {
  130. {
  131. .type = "not",
  132. .func_new = func_new_not,
  133. .func_die = func_die,
  134. .func_getvar = func_getvar
  135. }, {
  136. .type = "or",
  137. .func_new = func_new_or,
  138. .func_die = func_die,
  139. .func_getvar = func_getvar
  140. }, {
  141. .type = "and",
  142. .func_new = func_new_and,
  143. .func_die = func_die,
  144. .func_getvar = func_getvar
  145. }, {
  146. .type = NULL
  147. }
  148. };
  149. const struct NCDModuleGroup ncdmodule_logical = {
  150. .modules = modules
  151. };