Add permission subsystem
[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) {
112                         add(buffer, "not %c", c);
113                         if (val0 != smask) {
114                                 add(buffer, " and (");
115                                 mke(val0, bits - 1, buffer);
116                                 add(buffer, ")");
117                         }
118                 }
119                 if (val0 && val1)
120                         add(buffer, " or ");
121                 if (val1) {
122                         add(buffer, "%c", c);
123                         if (val1 != smask) {
124                                 add(buffer, " and (");
125                                 mke(val1, bits - 1, buffer);
126                                 add(buffer, ")");
127                         }
128                 }
129         } else {
130                 mke(val0, bits - 1, buffer);
131         }
132 }
133
134 void makeexpr(int value, char *buffer)
135 {
136         if (!value)
137                 strcpy(buffer, "x");
138         else {
139                 buffer[0] = 0;
140                 mke(value, 4, buffer);
141         }
142 }
143
144 int fulltest()
145 {
146         char buffer[4096];
147         int i, j, r;
148
149         r = 0;
150         for (i = 0 ; i < 65536 ; i++) {
151                 makeexpr(i, buffer);
152                 j = test(buffer);
153                 printf("[[[ %d %s %d ]]]\n", i, i==j?"==":"!=", j);
154                 if (i != j)
155                         r = 1;
156         }
157 }
158
159 int main()
160 {
161         int i = 0;
162         while(exprs[i])
163                 test(exprs[i++]);
164         return fulltest();
165 }
166