logical.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. // init arguments
  56. o->i = i;
  57. if (not) {
  58. NCDValue *arg;
  59. if (!NCDValue_ListRead(o->i->args, 1, &arg)) {
  60. ModuleLog(o->i, BLOG_ERROR, "wrong arity");
  61. goto fail1;
  62. }
  63. if (NCDValue_Type(arg) != NCDVALUE_STRING) {
  64. ModuleLog(o->i, BLOG_ERROR, "wrong type");
  65. goto fail1;
  66. }
  67. o->value = !!strcmp(NCDValue_StringValue(arg), "true");
  68. } else {
  69. NCDValue *arg1;
  70. NCDValue *arg2;
  71. if (!NCDValue_ListRead(o->i->args, 2, &arg1, &arg2)) {
  72. ModuleLog(o->i, BLOG_ERROR, "wrong arity");
  73. goto fail1;
  74. }
  75. if (NCDValue_Type(arg1) != NCDVALUE_STRING || NCDValue_Type(arg2) != NCDVALUE_STRING) {
  76. ModuleLog(o->i, BLOG_ERROR, "wrong type");
  77. goto fail1;
  78. }
  79. if (or) {
  80. o->value = (!strcmp(NCDValue_StringValue(arg1), "true") || !strcmp(NCDValue_StringValue(arg2), "true"));
  81. } else {
  82. o->value = (!strcmp(NCDValue_StringValue(arg1), "true") && !strcmp(NCDValue_StringValue(arg2), "true"));
  83. }
  84. }
  85. NCDModuleInst_Backend_Event(o->i, NCDMODULE_EVENT_UP);
  86. return o;
  87. fail1:
  88. free(o);
  89. fail0:
  90. return NULL;
  91. }
  92. static void * func_new_not (NCDModuleInst *i)
  93. {
  94. return func_new(i, 1, 0);
  95. }
  96. static void * func_new_or (NCDModuleInst *i)
  97. {
  98. return func_new(i, 0, 1);
  99. }
  100. static void * func_new_and (NCDModuleInst *i)
  101. {
  102. return func_new(i, 0, 0);
  103. }
  104. static void func_free (void *vo)
  105. {
  106. struct instance *o = vo;
  107. // free instance
  108. free(o);
  109. }
  110. static int func_getvar (void *vo, const char *name, NCDValue *out)
  111. {
  112. struct instance *o = vo;
  113. if (!strcmp(name, "")) {
  114. const char *v = (o->value ? "true" : "false");
  115. if (!NCDValue_InitString(out, v)) {
  116. ModuleLog(o->i, BLOG_ERROR, "NCDValue_InitString failed");
  117. return 0;
  118. }
  119. return 1;
  120. }
  121. return 0;
  122. }
  123. static const struct NCDModule modules[] = {
  124. {
  125. .type = "not",
  126. .func_new = func_new_not,
  127. .func_free = func_free,
  128. .func_getvar = func_getvar
  129. }, {
  130. .type = "or",
  131. .func_new = func_new_or,
  132. .func_free = func_free,
  133. .func_getvar = func_getvar
  134. }, {
  135. .type = "and",
  136. .func_new = func_new_and,
  137. .func_free = func_free,
  138. .func_getvar = func_getvar
  139. }, {
  140. .type = NULL
  141. }
  142. };
  143. const struct NCDModuleGroup ncdmodule_logical = {
  144. .modules = modules
  145. };