Prepare bindings version 2
[src/app-framework-binder.git] / src / tests / test-perm / test-perm.c
1 /*
2  * Copyright (C) 2017 "IoT.bzh"
3  * Author José Bollo <jose.bollo@iot.bzh>
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18
19 #include <stdio.h>
20 #include <stdarg.h>
21 #include <string.h>
22
23 #include "afb-perm.h"
24
25 char *exprs[] = {
26         "a",
27         "not a",
28         "a or b",
29         "a or b or c",
30         "a or b or c or d",
31         "a and b",
32         "a and b and c",
33         "a and b and c and d",
34         "a and b or c and d",
35         "a or b and c or d",
36         "(a or b) and (c or d)",
37         "not (a or b or c or d)",
38         "a and not (b or c or d)",
39         "b and not (a or c or d)",
40         "c and not (a or b or d)",
41         "d and not (a or b or c)",
42         NULL
43 };
44
45 int check(void *closure, const char *name)
46 {
47         int x;
48
49         x = *(int*)closure;
50         if (name[0] < 'a' || name[0] > 'd' || name[1])
51                 return 0;
52         return 1 & (x >> (name[0] - 'a'));
53 }
54
55 int test(const char *expr)
56 {
57         int x, r, m, c;
58         struct afb_perm *perm;
59
60         r = 0;
61         m = 1;
62         perm = afb_perm_parse(expr);
63         if (!perm)
64                 printf("error for %s\n", expr);
65         else {
66                 printf("\nabcd   %s\n", expr);
67                 for (x = 0; x < 16 ; x++) {
68                         c = afb_perm_check(perm, check, &x);
69                         printf("%c%c%c%c   %d\n",
70                                 '0'+!!(x&1), '0'+!!(x&2), '0'+!!(x&4), '0'+!!(x&8),
71                                 c);
72                         if (c)
73                                 r |= m;
74                         m <<= 1;
75                 }
76         }
77         afb_perm_unref(perm);
78         return r;
79 }
80
81 void add(char *buffer, const char *fmt, ...)
82 {
83         char b[60];
84         va_list vl;
85
86         va_start(vl, fmt);
87         vsprintf(b, fmt, vl);
88         va_end(vl);
89         strcat(buffer, b);
90 }
91
92 void mke(int value, int bits, char *buffer)
93 {
94         int nval = 1 << bits;
95         int sval = 1 << (bits - 1);
96         int mask = (1 << nval) - 1;
97         int smask = (1 << sval) - 1;
98         int val = value & mask;
99         int val0 = val & smask;
100         int val1 = (val >> sval) & smask;
101         char c = (char)('a' + bits - 1);
102
103         if (bits == 1) {
104                 switch(val) {
105                 case 0: add(buffer, "x"); break;
106                 case 1: add(buffer, "not %c", c); break;
107                 case 2: add(buffer, "%c", c); break;
108                 case 3: add(buffer, "(%c or not %c) ", c, c); break;
109                 }
110         } else if (val0 != val1) {
111                 if (val0 && val1)
112                         add(buffer, "(");
113                 if (val0) {
114                         add(buffer, "not %c", c);
115                         if (val0 != smask) {
116                                 add(buffer, " and ");
117                                 mke(val0, bits - 1, buffer);
118                         }
119                 }
120                 if (val0 && val1)
121                         add(buffer, " or ");
122                 if (val1) {
123                         add(buffer, "%c", c);
124                         if (val1 != smask) {
125                                 add(buffer, " and ");
126                                 mke(val1, bits - 1, buffer);
127                         }
128                 }
129                 if (val0 && val1)
130                         add(buffer, ")");
131         } else {
132                 mke(val0, bits - 1, buffer);
133         }
134 }
135
136 void makeexpr(int value, char *buffer)
137 {
138         if (!value)
139                 strcpy(buffer, "x");
140         else {
141                 buffer[0] = 0;
142                 mke(value, 4, buffer);
143         }
144 }
145
146 int fulltest()
147 {
148         char buffer[4096];
149         int i, j, r;
150
151         r = 0;
152         for (i = 0 ; i < 65536 ; i++) {
153                 makeexpr(i, buffer);
154                 j = test(buffer);
155                 printf("[[[ %d %s %d ]]] %d %s\n", i, i==j?"==":"!=", j, (int)strlen(buffer), buffer);
156                 if (i != j)
157                         r = 1;
158         }
159         return r;
160 }
161
162 int main()
163 {
164         int i = 0;
165         while(exprs[i])
166                 test(exprs[i++]);
167         return fulltest();
168 }
169