Added tarval_sub_bits() fucntion to access the (binary) bitpattern of a tarval.
[libfirm] / ir / tv / strcalc.c
1 /****i* strcalc/implementation
2  *
3  * AUTHORS
4  *    Matthias Heil
5  *
6  * NOTES
7  ******/
8
9 #include <assert.h>   /* assertions */
10 #include <string.h>   /* memset/memcmp */
11
12 #include "strcalc.h"
13
14 #include <stdio.h>    /* output for error messages */
15 #include <stdlib.h>
16
17 /*****************************************************************************
18  * local definitions and macros
19  *****************************************************************************/
20 #define BIT_PATTERN_SIZE (8 * BIGGEST_INTEGER_SIZE_IN_BYTES)
21 #define CALC_BUFFER_SIZE (4 * BIGGEST_INTEGER_SIZE_IN_BYTES)
22 #define MAX_VALUE_SIZE   (2 * BIGGEST_INTEGER_SIZE_IN_BYTES)
23
24 #define CLEAR_CALC_BUFFER() assert(calc_buffer); memset(calc_buffer, SC_0, CALC_BUFFER_SIZE)
25 #define _val(a) ((a)-SC_0)
26 #define _digit(a) ((a)+SC_0)
27 #define _bitisset(digit, pos) (and_table[_val(digit)][_val(shift_table[pos])] != SC_0)
28
29 #define fail_char(a, b, c, d) _fail_char((a), (b), (c), (d), __FILE__,  __LINE__)
30
31 #if 0
32 #  define DEBUGPRINTF(x) printf x
33 #else
34 #  define DEBUGPRINTF(x) ((void)0)
35 #endif
36
37 /*****************************************************************************
38  * private variables
39  *****************************************************************************/
40
41 static char calc_buffer[CALC_BUFFER_SIZE];    /* buffer holding all results */
42
43 static const char max_digit[4] = { SC_0, SC_1, SC_3, SC_7 };
44 static const char min_digit[4] = { SC_F, SC_E, SC_C, SC_8 };
45
46 static const char not_table[16] = { SC_F, SC_E, SC_D, SC_C, SC_B, SC_A, SC_9, SC_8,
47                               SC_7, SC_6, SC_5, SC_4, SC_3, SC_2, SC_1, SC_0 };
48
49 static const char shift_table[4] = { SC_1, SC_2, SC_4, SC_8 };
50
51 static const char and_table[16][16] = {
52                             { SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0,
53                               SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0 },
54
55                             { SC_0, SC_1, SC_0, SC_1, SC_0, SC_1, SC_0, SC_1,
56                               SC_0, SC_1, SC_0, SC_1, SC_0, SC_1, SC_0, SC_1 },
57
58                             { SC_0, SC_0, SC_2, SC_2, SC_0, SC_0, SC_2, SC_2,
59                               SC_0, SC_0, SC_2, SC_2, SC_0, SC_0, SC_2, SC_2 },
60
61                             { SC_0, SC_1, SC_2, SC_3, SC_0, SC_1, SC_2, SC_3,
62                               SC_0, SC_1, SC_2, SC_3, SC_0, SC_1, SC_2, SC_3 },
63
64                             { SC_0, SC_0, SC_0, SC_0, SC_4, SC_4, SC_4, SC_4,
65                               SC_0, SC_0, SC_0, SC_0, SC_4, SC_4, SC_4, SC_4 },
66
67                             { SC_0, SC_1, SC_0, SC_1, SC_4, SC_5, SC_4, SC_5,
68                               SC_0, SC_1, SC_0, SC_1, SC_4, SC_5, SC_4, SC_5 },
69
70                             { SC_0, SC_0, SC_2, SC_2, SC_4, SC_4, SC_6, SC_6,
71                               SC_0, SC_0, SC_2, SC_2, SC_4, SC_4, SC_6, SC_6 },
72
73                             { SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7,
74                               SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7 },
75
76                             { SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0, SC_0,
77                               SC_8, SC_8, SC_8, SC_8, SC_8, SC_8, SC_8, SC_8 },
78
79                             { SC_0, SC_1, SC_0, SC_1, SC_0, SC_1, SC_0, SC_1,
80                               SC_8, SC_9, SC_8, SC_9, SC_8, SC_9, SC_8, SC_9 },
81
82                             { SC_0, SC_0, SC_2, SC_2, SC_0, SC_0, SC_2, SC_2,
83                               SC_8, SC_8, SC_A, SC_A, SC_8, SC_8, SC_A, SC_A },
84
85                             { SC_0, SC_1, SC_2, SC_3, SC_0, SC_1, SC_2, SC_3,
86                               SC_8, SC_9, SC_A, SC_B, SC_8, SC_9, SC_A, SC_B },
87
88                             { SC_0, SC_0, SC_0, SC_0, SC_4, SC_4, SC_4, SC_4,
89                               SC_8, SC_8, SC_8, SC_8, SC_C, SC_C, SC_C, SC_C },
90
91                             { SC_0, SC_1, SC_0, SC_1, SC_4, SC_5, SC_4, SC_5,
92                               SC_8, SC_9, SC_8, SC_9, SC_D, SC_E, SC_D, SC_E },
93
94                             { SC_0, SC_0, SC_2, SC_2, SC_4, SC_4, SC_6, SC_6,
95                               SC_8, SC_8, SC_A, SC_A, SC_C, SC_C, SC_E, SC_E },
96
97                             { SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7,
98                               SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F } };
99
100 static const char or_table[16][16] = {
101                             { SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7,
102                               SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F },
103
104                             { SC_1, SC_1, SC_3, SC_3, SC_5, SC_5, SC_7, SC_7,
105                               SC_9, SC_9, SC_B, SC_B, SC_D, SC_D, SC_F, SC_F },
106
107                             { SC_2, SC_3, SC_2, SC_3, SC_6, SC_7, SC_6, SC_7,
108                               SC_A, SC_B, SC_A, SC_B, SC_E, SC_F, SC_E, SC_F },
109
110                             { SC_3, SC_3, SC_3, SC_3, SC_7, SC_7, SC_7, SC_7,
111                               SC_B, SC_B, SC_B, SC_B, SC_F, SC_F, SC_F, SC_F },
112
113                             { SC_4, SC_5, SC_6, SC_7, SC_4, SC_5, SC_6, SC_7,
114                               SC_C, SC_D, SC_E, SC_F, SC_C, SC_D, SC_E, SC_F },
115
116                             { SC_5, SC_5, SC_7, SC_7, SC_5, SC_5, SC_7, SC_7,
117                               SC_D, SC_D, SC_F, SC_F, SC_D, SC_D, SC_F, SC_F },
118
119                             { SC_6, SC_7, SC_6, SC_7, SC_6, SC_7, SC_6, SC_7,
120                               SC_E, SC_F, SC_E, SC_F, SC_E, SC_F, SC_E, SC_F },
121
122                             { SC_7, SC_7, SC_7, SC_7, SC_7, SC_7, SC_7, SC_7,
123                               SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F },
124
125                             { SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F,
126                               SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F },
127
128                             { SC_9, SC_9, SC_B, SC_B, SC_D, SC_D, SC_F, SC_F,
129                               SC_9, SC_9, SC_B, SC_B, SC_D, SC_D, SC_F, SC_F },
130
131                             { SC_A, SC_B, SC_A, SC_B, SC_E, SC_F, SC_E, SC_F,
132                               SC_A, SC_B, SC_A, SC_B, SC_E, SC_F, SC_E, SC_F },
133
134                             { SC_B, SC_B, SC_B, SC_B, SC_F, SC_F, SC_F, SC_F,
135                               SC_B, SC_B, SC_B, SC_B, SC_F, SC_F, SC_F, SC_F },
136
137                             { SC_C, SC_D, SC_E, SC_F, SC_C, SC_D, SC_E, SC_F,
138                               SC_C, SC_D, SC_E, SC_F, SC_C, SC_D, SC_E, SC_F },
139
140                             { SC_D, SC_D, SC_F, SC_F, SC_D, SC_D, SC_F, SC_F,
141                               SC_D, SC_D, SC_F, SC_F, SC_D, SC_D, SC_F, SC_F },
142
143                             { SC_E, SC_F, SC_E, SC_F, SC_E, SC_F, SC_E, SC_F,
144                               SC_E, SC_F, SC_E, SC_F, SC_E, SC_F, SC_E, SC_F },
145
146                             { SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F,
147                               SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F, SC_F } };
148
149 static char const xor_table[16][16] = {
150                              { SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7,
151                                SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F },
152
153                              { SC_1, SC_0, SC_3, SC_2, SC_5, SC_4, SC_7, SC_6,
154                                SC_9, SC_8, SC_B, SC_A, SC_D, SC_C, SC_F, SC_E },
155
156                              { SC_2, SC_3, SC_0, SC_1, SC_6, SC_7, SC_4, SC_5,
157                                SC_A, SC_B, SC_8, SC_9, SC_E, SC_F, SC_C, SC_D },
158
159                              { SC_3, SC_2, SC_1, SC_0, SC_7, SC_6, SC_5, SC_4,
160                                SC_B, SC_A, SC_9, SC_8, SC_F, SC_E, SC_D, SC_C },
161
162                              { SC_4, SC_5, SC_6, SC_7, SC_0, SC_1, SC_2, SC_3,
163                                SC_C, SC_D, SC_E, SC_F, SC_8, SC_9, SC_A, SC_B },
164
165                              { SC_5, SC_4, SC_7, SC_6, SC_1, SC_0, SC_3, SC_2,
166                                SC_D, SC_C, SC_F, SC_E, SC_9, SC_8, SC_B, SC_A },
167
168                              { SC_6, SC_7, SC_4, SC_5, SC_2, SC_3, SC_0, SC_1,
169                                SC_E, SC_F, SC_C, SC_D, SC_A, SC_B, SC_8, SC_9 },
170
171                              { SC_7, SC_6, SC_5, SC_4, SC_3, SC_2, SC_1, SC_0,
172                                SC_F, SC_E, SC_D, SC_C, SC_B, SC_A, SC_9, SC_8 },
173
174                              { SC_8, SC_9, SC_A, SC_B, SC_C, SC_D, SC_E, SC_F,
175                                SC_0, SC_1, SC_2, SC_3, SC_4, SC_5, SC_6, SC_7 },
176
177                              { SC_9, SC_8, SC_B, SC_A, SC_D, SC_C, SC_F, SC_E,
178                                SC_1, SC_0, SC_3, SC_2, SC_5, SC_4, SC_7, SC_6 },
179
180                              { SC_A, SC_B, SC_8, SC_9, SC_E, SC_F, SC_C, SC_D,
181                                SC_2, SC_3, SC_0, SC_1, SC_6, SC_7, SC_4, SC_5 },
182
183                              { SC_B, SC_A, SC_9, SC_8, SC_F, SC_E, SC_D, SC_C,
184                                SC_3, SC_2, SC_1, SC_0, SC_7, SC_6, SC_5, SC_4 },
185
186                              { SC_C, SC_D, SC_E, SC_F, SC_8, SC_9, SC_A, SC_B,
187                                SC_4, SC_5, SC_6, SC_7, SC_0, SC_1, SC_2, SC_3 },
188
189                              { SC_D, SC_C, SC_F, SC_E, SC_9, SC_8, SC_B, SC_A,
190                                SC_5, SC_4, SC_7, SC_6, SC_1, SC_0, SC_3, SC_2 },
191
192                              { SC_E, SC_F, SC_C, SC_D, SC_A, SC_B, SC_8, SC_9,
193                                SC_6, SC_7, SC_4, SC_5, SC_2, SC_3, SC_0, SC_1 },
194
195                              { SC_F, SC_E, SC_D, SC_C, SC_B, SC_A, SC_9, SC_8,
196                                SC_7, SC_6, SC_5, SC_4, SC_3, SC_2, SC_1, SC_0 }
197                                 };
198
199 static char const add_table[16][16][2] = {
200                        { {SC_0, SC_0}, {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0},
201                          {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
202                          {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
203                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0} },
204
205                        { {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0}, {SC_4, SC_0},
206                          {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0},
207                          {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
208                          {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1} },
209
210                        { {SC_2, SC_0}, {SC_3, SC_0}, {SC_4, SC_0}, {SC_5, SC_0},
211                          {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0},
212                          {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
213                          {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1} },
214
215                        { {SC_3, SC_0}, {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0},
216                          {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0},
217                          {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
218                          {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1} },
219
220                        { {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
221                          {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
222                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
223                          {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1} },
224
225                        { {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0},
226                          {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
227                          {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
228                          {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1} },
229
230                        { {SC_6, SC_0}, {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0},
231                          {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
232                          {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
233                          {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1} },
234
235                        { {SC_7, SC_0}, {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0},
236                          {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
237                          {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
238                          {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1} },
239
240                        { {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
241                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
242                          {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1},
243                          {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1} },
244
245                        { {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0},
246                          {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
247                          {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1},
248                          {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1} },
249
250                        { {SC_A, SC_0}, {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0},
251                          {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
252                          {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1},
253                          {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1} },
254
255                        { {SC_B, SC_0}, {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0},
256                          {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
257                          {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1},
258                          {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1} },
259
260                        { {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0},
261                          {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1},
262                          {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1},
263                          {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1}, {SC_B, SC_1} },
264
265                        { {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1},
266                          {SC_1, SC_1}, {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1},
267                          {SC_5, SC_1}, {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1},
268                          {SC_9, SC_1}, {SC_A, SC_1}, {SC_B, SC_1}, {SC_C, SC_1} },
269
270                        { {SC_E, SC_0}, {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1},
271                          {SC_2, SC_1}, {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1},
272                          {SC_6, SC_1}, {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1},
273                          {SC_A, SC_1}, {SC_B, SC_1}, {SC_C, SC_1}, {SC_D, SC_1} },
274
275                        { {SC_F, SC_0}, {SC_0, SC_1}, {SC_1, SC_1}, {SC_2, SC_1},
276                          {SC_3, SC_1}, {SC_4, SC_1}, {SC_5, SC_1}, {SC_6, SC_1},
277                          {SC_7, SC_1}, {SC_8, SC_1}, {SC_9, SC_1}, {SC_A, SC_1},
278                          {SC_B, SC_1}, {SC_C, SC_1}, {SC_D, SC_1}, {SC_E, SC_1} }
279                              };
280
281 static char const mul_table[16][16][2] = {
282                        { {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
283                          {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
284                          {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0},
285                          {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0} },
286
287                        { {SC_0, SC_0}, {SC_1, SC_0}, {SC_2, SC_0}, {SC_3, SC_0},
288                          {SC_4, SC_0}, {SC_5, SC_0}, {SC_6, SC_0}, {SC_7, SC_0},
289                          {SC_8, SC_0}, {SC_9, SC_0}, {SC_A, SC_0}, {SC_B, SC_0},
290                          {SC_C, SC_0}, {SC_D, SC_0}, {SC_E, SC_0}, {SC_F, SC_0} },
291
292                        { {SC_0, SC_0}, {SC_2, SC_0}, {SC_4, SC_0}, {SC_6, SC_0},
293                          {SC_8, SC_0}, {SC_A, SC_0}, {SC_C, SC_0}, {SC_E, SC_0},
294                          {SC_0, SC_1}, {SC_2, SC_1}, {SC_4, SC_1}, {SC_6, SC_1},
295                          {SC_8, SC_1}, {SC_A, SC_1}, {SC_C, SC_1}, {SC_E, SC_1} },
296
297                        { {SC_0, SC_0}, {SC_3, SC_0}, {SC_6, SC_0}, {SC_9, SC_0},
298                          {SC_C, SC_0}, {SC_F, SC_0}, {SC_2, SC_1}, {SC_5, SC_1},
299                          {SC_8, SC_1}, {SC_B, SC_1}, {SC_E, SC_1}, {SC_1, SC_2},
300                          {SC_4, SC_2}, {SC_7, SC_2}, {SC_A, SC_2}, {SC_D, SC_2} },
301
302                        { {SC_0, SC_0}, {SC_4, SC_0}, {SC_8, SC_0}, {SC_C, SC_0},
303                          {SC_0, SC_1}, {SC_4, SC_1}, {SC_8, SC_1}, {SC_C, SC_1},
304                          {SC_0, SC_2}, {SC_4, SC_2}, {SC_8, SC_2}, {SC_C, SC_2},
305                          {SC_0, SC_3}, {SC_4, SC_3}, {SC_8, SC_3}, {SC_C, SC_3} },
306
307                        { {SC_0, SC_0}, {SC_5, SC_0}, {SC_A, SC_0}, {SC_F, SC_0},
308                          {SC_4, SC_1}, {SC_9, SC_1}, {SC_E, SC_1}, {SC_3, SC_2},
309                          {SC_8, SC_2}, {SC_D, SC_2}, {SC_2, SC_3}, {SC_7, SC_3},
310                          {SC_C, SC_3}, {SC_1, SC_4}, {SC_6, SC_4}, {SC_B, SC_4} },
311
312                        { {SC_0, SC_0}, {SC_6, SC_0}, {SC_C, SC_0}, {SC_2, SC_1},
313                          {SC_8, SC_1}, {SC_E, SC_1}, {SC_4, SC_2}, {SC_A, SC_2},
314                          {SC_0, SC_3}, {SC_6, SC_3}, {SC_C, SC_3}, {SC_2, SC_4},
315                          {SC_8, SC_4}, {SC_E, SC_4}, {SC_4, SC_5}, {SC_A, SC_5} },
316
317                        { {SC_0, SC_0}, {SC_7, SC_0}, {SC_E, SC_0}, {SC_5, SC_1},
318                          {SC_C, SC_1}, {SC_3, SC_2}, {SC_A, SC_2}, {SC_1, SC_3},
319                          {SC_8, SC_3}, {SC_F, SC_3}, {SC_6, SC_4}, {SC_D, SC_4},
320                          {SC_4, SC_5}, {SC_B, SC_5}, {SC_2, SC_6}, {SC_9, SC_6} },
321
322                        { {SC_0, SC_0}, {SC_8, SC_0}, {SC_0, SC_1}, {SC_8, SC_1},
323                          {SC_0, SC_2}, {SC_8, SC_2}, {SC_0, SC_3}, {SC_8, SC_3},
324                          {SC_0, SC_4}, {SC_8, SC_4}, {SC_0, SC_5}, {SC_8, SC_5},
325                          {SC_0, SC_6}, {SC_8, SC_6}, {SC_0, SC_7}, {SC_8, SC_7} },
326
327                        { {SC_0, SC_0}, {SC_9, SC_0}, {SC_2, SC_1}, {SC_B, SC_1},
328                          {SC_4, SC_2}, {SC_D, SC_2}, {SC_6, SC_3}, {SC_F, SC_3},
329                          {SC_8, SC_4}, {SC_1, SC_5}, {SC_A, SC_5}, {SC_3, SC_6},
330                          {SC_C, SC_6}, {SC_5, SC_7}, {SC_E, SC_7}, {SC_7, SC_8} },
331
332                        { {SC_0, SC_0}, {SC_A, SC_0}, {SC_4, SC_1}, {SC_E, SC_1},
333                          {SC_8, SC_2}, {SC_2, SC_3}, {SC_C, SC_3}, {SC_6, SC_4},
334                          {SC_0, SC_5}, {SC_A, SC_5}, {SC_4, SC_6}, {SC_E, SC_6},
335                          {SC_8, SC_7}, {SC_2, SC_8}, {SC_C, SC_8}, {SC_6, SC_9} },
336
337                        { {SC_0, SC_0}, {SC_B, SC_0}, {SC_6, SC_1}, {SC_1, SC_2},
338                          {SC_C, SC_2}, {SC_7, SC_3}, {SC_2, SC_4}, {SC_D, SC_4},
339                          {SC_8, SC_5}, {SC_3, SC_6}, {SC_E, SC_6}, {SC_9, SC_7},
340                          {SC_4, SC_8}, {SC_F, SC_8}, {SC_A, SC_9}, {SC_5, SC_A} },
341
342                        { {SC_0, SC_0}, {SC_C, SC_0}, {SC_8, SC_1}, {SC_4, SC_2},
343                          {SC_0, SC_3}, {SC_C, SC_3}, {SC_8, SC_4}, {SC_4, SC_5},
344                          {SC_0, SC_6}, {SC_C, SC_6}, {SC_8, SC_7}, {SC_4, SC_8},
345                          {SC_0, SC_9}, {SC_C, SC_9}, {SC_8, SC_A}, {SC_4, SC_B} },
346
347                        { {SC_0, SC_0}, {SC_D, SC_0}, {SC_A, SC_1}, {SC_7, SC_2},
348                          {SC_4, SC_3}, {SC_1, SC_4}, {SC_E, SC_4}, {SC_B, SC_5},
349                          {SC_8, SC_6}, {SC_5, SC_7}, {SC_2, SC_8}, {SC_F, SC_8},
350                          {SC_C, SC_9}, {SC_9, SC_A}, {SC_6, SC_B}, {SC_3, SC_C} },
351
352                        { {SC_0, SC_0}, {SC_E, SC_0}, {SC_C, SC_1}, {SC_A, SC_2},
353                          {SC_8, SC_3}, {SC_6, SC_4}, {SC_4, SC_5}, {SC_2, SC_6},
354                          {SC_0, SC_7}, {SC_E, SC_7}, {SC_C, SC_8}, {SC_A, SC_9},
355                          {SC_8, SC_A}, {SC_6, SC_B}, {SC_4, SC_C}, {SC_2, SC_D} },
356
357                        { {SC_0, SC_0}, {SC_F, SC_0}, {SC_E, SC_1}, {SC_D, SC_2},
358                          {SC_C, SC_3}, {SC_B, SC_4}, {SC_A, SC_5}, {SC_9, SC_6},
359                          {SC_8, SC_7}, {SC_7, SC_8}, {SC_6, SC_9}, {SC_5, SC_A},
360                          {SC_4, SC_B}, {SC_3, SC_C}, {SC_2, SC_D}, {SC_1, SC_E} }
361                              };
362
363 static char const shrs_table[16][4][2] = {
364                        { {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0}, {SC_0, SC_0} },
365                        { {SC_1, SC_0}, {SC_0, SC_8}, {SC_0, SC_4}, {SC_0, SC_2} },
366                        { {SC_2, SC_0}, {SC_1, SC_0}, {SC_0, SC_8}, {SC_0, SC_4} },
367                        { {SC_3, SC_0}, {SC_1, SC_8}, {SC_0, SC_C}, {SC_0, SC_6} },
368                        { {SC_4, SC_0}, {SC_2, SC_0}, {SC_1, SC_0}, {SC_0, SC_8} },
369                        { {SC_5, SC_0}, {SC_2, SC_8}, {SC_1, SC_4}, {SC_0, SC_A} },
370                        { {SC_6, SC_0}, {SC_3, SC_0}, {SC_1, SC_8}, {SC_0, SC_C} },
371                        { {SC_7, SC_0}, {SC_3, SC_8}, {SC_1, SC_C}, {SC_0, SC_E} },
372                        { {SC_8, SC_0}, {SC_4, SC_0}, {SC_2, SC_0}, {SC_1, SC_0} },
373                        { {SC_9, SC_0}, {SC_4, SC_8}, {SC_2, SC_4}, {SC_1, SC_2} },
374                        { {SC_A, SC_0}, {SC_5, SC_0}, {SC_2, SC_8}, {SC_1, SC_4} },
375                        { {SC_B, SC_0}, {SC_5, SC_8}, {SC_2, SC_C}, {SC_1, SC_6} },
376                        { {SC_C, SC_0}, {SC_6, SC_0}, {SC_3, SC_0}, {SC_1, SC_8} },
377                        { {SC_D, SC_0}, {SC_6, SC_8}, {SC_3, SC_4}, {SC_1, SC_A} },
378                        { {SC_E, SC_0}, {SC_7, SC_0}, {SC_3, SC_8}, {SC_1, SC_C} },
379                        { {SC_F, SC_0}, {SC_7, SC_8}, {SC_3, SC_C}, {SC_1, SC_E} }
380                                    };
381 /*****************************************************************************
382  * private functions
383  *****************************************************************************/
384 static void _fail_char(const char *str, size_t len, const char fchar, int pos,
385                        const char *file, int line)
386 {
387   printf("ERROR:\n");
388   printf("Unexpected character '%c' in %s:%d\n", fchar, file, line);
389   while (len-- && *str) printf("%c", *str++); printf("\n");
390   while (--pos) printf(" "); printf("^\n");
391   exit(-1);
392 }
393
394 static void _bitnot(const char *val, char *buffer)
395 {
396   int counter;
397
398   for (counter = 0; counter<CALC_BUFFER_SIZE; counter++)
399     buffer[counter] = not_table[_val(val[counter])];
400 }
401
402 static void _bitor(const char *val1, const char *val2, char *buffer)
403 {
404   int counter;
405
406   for (counter = 0; counter<CALC_BUFFER_SIZE; counter++)
407     buffer[counter] = or_table[_val(val1[counter])][_val(val2[counter])];
408 }
409
410 static void _bitxor(const char *val1, const char *val2, char *buffer)
411 {
412   int counter;
413
414   for (counter = 0; counter<CALC_BUFFER_SIZE; counter++)
415     buffer[counter] = xor_table[_val(val1[counter])][_val(val2[counter])];
416 }
417
418 static void _bitand(const char *val1, const char *val2, char *buffer)
419 {
420   int counter;
421
422   for (counter = 0; counter<CALC_BUFFER_SIZE; counter++)
423     buffer[counter] = and_table[_val(val1[counter])][_val(val2[counter])];
424 }
425
426 static int _sign(const char *val)
427 {
428   return (val[CALC_BUFFER_SIZE-1] < SC_7) ? (1) : (-1);
429 }
430
431 static void _inc(char *val, char *buffer)
432 {
433   int counter = 0;
434
435   while (counter++ < CALC_BUFFER_SIZE)
436   {
437     if (*val == SC_F)
438     {
439       *buffer++ = SC_0;
440       val++;
441     }
442     else
443     {
444       /* No carry here, *val != SC_F */
445       *buffer = add_table[_val(*val)][SC_1][0];
446       return;
447     }
448   }
449   /* here a carry could be lost, this is intended because this will only
450    * happen when a value changes sign. */
451 }
452
453 static void _negate(const char *val, char *buffer)
454 {
455   _bitnot(val, buffer);
456   _inc(buffer, buffer);
457 }
458
459 static void _add(const char *val1, const char *val2, char *buffer)
460 {
461   int counter;
462   const char *add1, *add2;
463   char carry = SC_0;
464
465   for (counter = 0; counter < CALC_BUFFER_SIZE; counter++)
466   {
467     add1 = add_table[_val(val1[counter])][_val(val2[counter])];
468     add2 = add_table[_val(add1[0])][_val(carry)];
469     /* carry might be zero */
470     buffer[counter] = add2[0];
471     carry = add_table[_val(add1[1])][_val(add2[1])][0];
472   }
473   /* loose last carry, which will occur only when changing sign */
474 }
475
476 static void _mul(const char *val1, const char *val2, char *buffer)
477 {
478   char temp_buffer[CALC_BUFFER_SIZE]; /* result buffer */
479   char neg_val1[CALC_BUFFER_SIZE];    /* abs of val1 */
480   char neg_val2[CALC_BUFFER_SIZE];    /* abs of val2 */
481
482   const char *mul, *add1, *add2;      /* intermediate result containers */
483   char carry = SC_0;                  /* container for carries */
484   char sign = 0;                      /* marks result sign */
485   int c_inner, c_outer;               /* loop counters */
486
487   /* init result buffer to zeroes */
488   memset(temp_buffer, SC_0, CALC_BUFFER_SIZE);
489
490   /* the multiplication works only for positive values, for negative values *
491    * it is necessary to negate them and adjust the result accordingly       */
492   if (_sign(val1) == -1) {
493     _negate(val1, neg_val1);
494     val1 = neg_val1;
495     sign ^= 1;
496   }
497   if (_sign(val2) == -1) {
498     _negate(val2, neg_val2);
499     val2 = neg_val2;
500     sign ^= 1;
501   }
502
503   for (c_outer = 0; c_outer < MAX_VALUE_SIZE; c_outer++)
504   {
505     if (val2[c_outer] != SC_0)
506     {
507       for (c_inner = 0; c_inner < MAX_VALUE_SIZE; c_inner++)
508       {
509         /* do the following calculation:                                    *
510          * Add the current carry, the value at position c_outer+c_inner     *
511          * and the result of the multiplication of val1[c_inner] and        *
512          * val2[c_outer]. This is the usual pen-and-paper multiplication.   */
513
514         /* multiplicate the two digits */
515         mul = mul_table[_val(val1[c_inner])][_val(val2[c_outer])];
516         /* add old value to result of multiplication */
517         add1 = add_table[_val(temp_buffer[c_inner + c_outer])][_val(mul[0])];
518         /* add carry to the sum */
519         add2 = add_table[_val(add1[0])][_val(carry)];
520
521         /* all carries together result in new carry. This is always smaller *
522          * than the base b:                                                 *
523          * Both multiplicands, the carry and the value already in the temp  *
524          * buffer are single digits and their value is therefore at most    *
525          * equal to (b-1).                                                  *
526          * This leads to:                                                   *
527          * (b-1)(b-1)+(b-1)+(b-1) = b*b-1                                   *
528          * The tables list all operations rem b, so the carry is at most    *
529          * (b*b-1)rem b = -1rem b = b-1                                     */
530         carry = add_table[_val(mul[1])][_val(add1[1])][0];
531         carry = add_table[_val(carry)][_val(add2[1])][0];
532
533         temp_buffer[c_inner + c_outer] = add2[0];
534       }
535
536       /* A carry may hang over */
537       /* c_outer is always smaller than MAX_VALUE_SIZE! */
538       temp_buffer[MAX_VALUE_SIZE + c_outer] = carry;
539     }
540   }
541
542   if (sign)
543     _negate(temp_buffer, buffer);
544   else
545     memcpy(buffer, temp_buffer, CALC_BUFFER_SIZE);
546 }
547
548 static void _sub(const char *val1, const char *val2, char *buffer)
549 {
550   char temp_buffer[CALC_BUFFER_SIZE];  /* intermediate buffer to hold -val2 */
551
552   _negate(val2, temp_buffer);
553   _add(val1, temp_buffer, buffer);
554 }
555
556 static void _push(const char digit, char *buffer)
557 {
558   int counter;
559
560   for (counter = CALC_BUFFER_SIZE - 2; counter >= 0; counter--)
561   {
562     buffer[counter+1] = buffer[counter];
563   }
564   buffer[0] = digit;
565 }
566
567 /* XXX: This is MOST slow */
568 static void _divmod(const char *dividend, const char *divisor, char *quot, char *rem)
569 {
570   const char *minus_divisor;
571   char neg_val1[CALC_BUFFER_SIZE];
572   char neg_val2[CALC_BUFFER_SIZE];
573
574   char sign = 0;     /* remember result sign */
575
576   int c_dividend;      /* loop counters */
577
578   /* clear result buffer */
579   memset(quot, SC_0, CALC_BUFFER_SIZE);
580   memset(rem, SC_0, CALC_BUFFER_SIZE);
581
582   /* if the dividend is zero result is zero (quot is zero)*/
583   if (sc_comp(dividend, quot) == 0) return;
584   /* if the divisor is zero this won't work (quot is zero) */
585   if (sc_comp(divisor, quot) == 0) assert(0 && "quotision by zero!");
586
587   if (_sign(dividend) == -1)
588   {
589     _negate(dividend, neg_val1);
590     sign ^= 1;
591     dividend = neg_val1;
592   }
593
594   _negate(divisor, neg_val2);
595   if (_sign(divisor) == -1)
596   {
597     sign ^= 1;
598     minus_divisor = divisor;
599     divisor = neg_val2;
600   }
601   else
602   {
603     minus_divisor = neg_val2;
604   }
605
606   /* if divisor >= dividend quotision is easy
607    * (remember these are absolute values) */
608   switch (sc_comp(dividend, divisor))
609   {
610     case 0: /* dividend == divisor */
611       quot[0] = SC_1;
612       return;
613
614     case -1: /* dividend < divisor */
615       memcpy(rem, dividend, CALC_BUFFER_SIZE);
616       return;
617
618     default: /* unluckily quotision is necessary :( */
619       break;
620   }
621
622   for (c_dividend = MAX_VALUE_SIZE - 1; c_dividend >= 0; c_dividend--)
623   {
624     _push(dividend[c_dividend], rem);
625     _push(SC_0, quot);
626
627     if (sc_comp(rem, divisor) != -1)    /* remainder >= divisor */
628     {
629       /* subtract until the remainder becomes negative, this should
630        * be faster than comparing remainder with divisor  */
631       _add(rem, minus_divisor, rem);
632
633       while (_sign(rem) == 1)
634       {
635         quot[0] = add_table[_val(quot[0])][SC_1][0];
636         _add(rem, minus_divisor, rem);
637       }
638
639       /* subtracted one too much */
640       _add(rem, divisor, rem);
641     }
642   }
643
644   if (sign)
645   {
646     _negate(quot, quot);
647     _negate(rem, rem);
648   }
649 }
650
651 static void _shl(const char *val1, const char *val2, char *buffer, unsigned radius, unsigned is_signed)
652 {
653   const char *shl;
654   char shift;
655   char carry = SC_0;
656
657   int counter;
658   int offset = 0;
659   int bitoffset = 0;
660
661   assert((_sign(val2) != -1) || (0 && "negative leftshift"));
662   assert(((_sign(val1) != -1) || is_signed) || (0 && "unsigned mode and negative value"));
663   assert(((!_bitisset(val1[(radius-1)/4], (radius-1)%4)) || !is_signed || (_sign(val1) == -1)) || (0 && "value is positive, should be negative"));
664   assert(((_bitisset(val1[(radius-1)/4], (radius-1)%4)) || !is_signed || (_sign(val1) == 1)) || (0 && "value is negative, should be positive"));
665
666   /* the whole value must be moved left the number of bytes represented
667    * by the value in quot, with bytes to the right set to zero */
668   /*XXX This might result in trouble */
669   for (counter = MAX_VALUE_SIZE - 1; counter >= 0; counter--)
670   {
671     offset = (offset << 4) | (_val(val2[counter]));
672   }
673
674   shift = shift_table[_val(offset%4)];      /* this is 2 ** (val2 % 4) */
675
676   /* if shifting far enough the result is zero */
677   if (offset >= radius)
678   {
679     memset(buffer, SC_0, CALC_BUFFER_SIZE);
680     return;
681   }
682   offset = offset / 4;
683
684   /* shift the single digits some bytes (offset) and some bits (table)
685    * to the left */
686   for (counter = 0; counter < CALC_BUFFER_SIZE - offset; counter++)
687   {
688     shl = mul_table[_val(val1[counter])][_val(shift)];
689     buffer[counter + offset] = or_table[_val(shl[0])][_val(carry)];
690     carry = shl[1];
691   }
692
693   /* fill with zeroes */
694   for (counter = 0; counter < offset; counter++) buffer[counter] = 0;
695   /* if the mode was signed, change sign when the mode's msb is now 1 */
696   offset = (radius - 1) / 4;
697   bitoffset = (radius - 1) % 4;
698   if (is_signed && _bitisset(buffer[offset], bitoffset) && (_sign(buffer) == 1))
699   {
700     /* this sets the upper bits of the leftmost digit */
701     buffer[offset] = or_table[_val(buffer[offset])][_val(min_digit[bitoffset])];
702     for (counter = offset+1; counter < CALC_BUFFER_SIZE; counter++)
703     {
704       buffer[counter] = SC_F;
705     }
706   }
707   else if (is_signed && !_bitisset(buffer[offset], bitoffset) && (_sign(buffer) == -1))
708   {
709     /* this unsets the upper bits of the leftmost digit */
710     buffer[offset] = and_table[_val(buffer[offset])][_val(max_digit[bitoffset])];
711     /* zero the upper part of the value */
712     for (counter = offset+1; counter < CALC_BUFFER_SIZE; counter++)
713     {
714       buffer[counter] = SC_0;
715     }
716   }
717 }
718
719 static void _shr(const char *val1, const char *val2, char *buffer, unsigned radius, unsigned is_signed, int signed_shift)
720 {
721   const char *shrs;
722   char sign;
723   char msd;
724
725   int shift;
726
727   int counter;
728   int offset = 0;
729   int bitoffset = 0;
730
731   assert((_sign(val2) != -1) || (0 && "negative rightshift"));
732   assert(((_sign(val1) != -1) || is_signed) || (0 && "unsigned mode and negative value"));
733   assert(((!_bitisset(val1[(radius-1)/4], (radius-1)%4)) || !is_signed || (_sign(val1) == -1)) || (0 && "value is positive, should be negative"));
734   assert(((_bitisset(val1[(radius-1)/4], (radius-1)%4)) || !is_signed || (_sign(val1) == 1)) || (0 && "value is negative, should be positive"));
735
736   /*XXX get the value of val2, this might result in trouble *
737    * (but who wants shifts THAT far anyway)                 */
738   for (counter = MAX_VALUE_SIZE - 1; counter >= 0; counter--)
739   {
740     offset = (offset << 4) | (_val(val2[counter]));
741   }
742
743   shift = offset % 4;     /* this is val2 % 4 */
744
745   sign = ((signed_shift) && (_sign(val1) == -1))?(SC_F):(SC_0);
746   /* if shifting far enough the result is either 0 or -1 */
747   if (offset >= radius)
748   {
749     memset(buffer, sign, CALC_BUFFER_SIZE);
750     return;
751   }
752   offset = offset / 4;
753
754   buffer[0] = shrs_table[_val(val1[offset])][shift][0];
755   /* shift digits to the right with offset, carry and all */
756   for (counter = 1; counter < radius/4; counter++)
757   {
758     shrs = shrs_table[_val(val1[counter + offset])][shift];
759     buffer[counter] = shrs[0];
760     buffer[counter-1] = or_table[_val(buffer[counter-1])][_val(shrs[1])];
761   }
762
763   /* the last digit is special in regard of signed/unsigned shift */
764   /* counter = radius/4 (after for loop) */
765   bitoffset = radius%4;
766   msd = val1[counter];  /* most significant digit */
767
768   /* remove sign bits if mode was signed and this is an unsigned shift */
769   if (!signed_shift && is_signed) {
770     msd = and_table[_val(msd)][_val(max_digit[bitoffset])];
771   }
772
773   shrs = shrs_table[_val(msd)][shift];
774
775   /* signed shift and signed mode and negative value means all bits to the left are set */
776   if (signed_shift && is_signed && (_sign(val1) == -1)) {
777     buffer[counter] = or_table[_val(shrs[0])][_val(min_digit[bitoffset])];
778   } else {
779     buffer[counter] = shrs[0];
780   }
781   buffer[counter - 1] = or_table[_val(buffer[counter-1])][_val(shrs[1])];
782
783   /* fill with SC_F or SC_0 depending on sign */
784   for (counter++; counter < CALC_BUFFER_SIZE; counter++)
785   {
786     buffer[counter] = sign;
787   }
788 }
789
790 /* positive: low-order -> high order, negative other direction */
791 static void _rot(const char *val1, const char *val2, char *buffer, unsigned radius, unsigned is_signed)
792 {
793   char temp_buffer[CALC_BUFFER_SIZE];
794
795   const char *shl;
796   char carry = SC_0;
797
798   int counter, old_counter;
799   int shift;
800   int offset = 0;
801   int bitoffset;
802
803   /*XXX get the value of val2, this might result in trouble *
804    * (but who wants shifts THAT far anyway)                 */
805   for (counter = MAX_VALUE_SIZE - 1; counter >= 0; counter--)
806   {
807     offset = (offset << 4) | (_val(val2[counter]));
808   }
809   /* rotation by multiples of the typelength is identity */
810   offset = offset % radius;
811   if (offset == 0) {
812     memmove(buffer, val1, CALC_BUFFER_SIZE);
813     return;
814   }
815   /* rotation to the right is the same as rotation to the left
816    * when done by the right amount */
817   if (offset < 0) offset = radius + offset;
818
819   shift = _val(shift_table[offset % 4]);
820   offset = offset / 4;
821
822   DEBUGPRINTF(("offset: %d, shift: %d\n", offset, shift));
823   for (counter = 0; counter < radius/4 - offset; counter++)
824   {
825     shl = mul_table[_val(val1[counter])][_val(shift)];
826     temp_buffer[counter + offset] = or_table[_val(shl[0])][_val(carry)];
827     carry = shl[1];
828     DEBUGPRINTF(("%d(%x): %s\n", counter, shl[0], sc_print_hex(temp_buffer)));
829   }
830   old_counter = counter;
831   for (; counter < radius/4; counter++)
832   {
833     shl = mul_table[_val(val1[counter])][_val(shift)];
834     temp_buffer[counter - old_counter] = or_table[_val(shl[0])][_val(carry)];
835     carry = shl[1];
836     DEBUGPRINTF(("%d(%x)> %s\n", counter, shl[0], sc_print_hex(temp_buffer)));
837   }
838   temp_buffer[counter - old_counter] = or_table[_val(temp_buffer[counter-old_counter])][_val(carry)];
839
840   offset = (radius-1)/4;
841   bitoffset - (radius-1)%4;
842   /* fill the rest of the buffer depending on msb and mode signedness*/
843   if (is_signed && _bitisset(temp_buffer[offset], bitoffset))
844   {
845
846   }
847   else
848   {
849
850   }
851
852   memcpy(buffer, temp_buffer, CALC_BUFFER_SIZE);
853 }
854
855 /*****************************************************************************
856  * public functions, declared in strcalc.h
857  *****************************************************************************/
858 const void *sc_get_buffer(void)
859 {
860   return (void*)calc_buffer;
861 }
862
863 const int sc_get_buffer_length(void)
864 {
865   return CALC_BUFFER_SIZE;
866 }
867
868 void sc_val_from_str(const char *str, unsigned int len)
869 {
870   const char *orig_str = str;
871   unsigned int orig_len = len;
872
873   char sign = 0;
874   char base[CALC_BUFFER_SIZE];
875   char val[CALC_BUFFER_SIZE];
876
877   /* verify valid pointers (not null) */
878   assert(str);
879   /* a string no characters long is an error */
880   assert(len);
881
882   CLEAR_CALC_BUFFER();
883   memset(base, SC_0, CALC_BUFFER_SIZE);
884   memset(val, SC_0, CALC_BUFFER_SIZE);
885
886   /* strip leading spaces */
887   while ((len > 0) && (*str == ' ')) { len--; str++; }
888
889   /* if the first two characters are 0x or 0X -> hex
890    * if the first is a 0 -> oct
891    * else dec, strip leading -/+ and remember sign
892    *
893    * only a + or - sign is no number resulting in an error */
894   if (len >= 2)
895     switch (str[0])
896     {
897       case '0':
898         if (str[1] == 'x' || str[1] == 'X') /* hex */
899         {
900           str += 2;
901           len -= 2;
902           base[1] = SC_1; base[0] = SC_0;
903         }
904         else /* oct */
905         {
906           str += 1;
907           len -= 1;
908           base[1] = SC_0; base[0] = SC_8;
909         }
910         break;
911
912       case '+':
913         {
914           str += 1;
915           len -= 1;
916           base[1] = SC_0; base[0] = SC_A;
917         }
918         break;
919
920       case '-':
921         {
922           str += 1;
923           len -= 1;
924           sign = 1;
925           base[1] = SC_0; base[0] = SC_A;
926         }
927         break;
928
929       default: /* dec, else would have begun with 0x or 0 */
930         base[1] = SC_0; base[0] = SC_A;
931     }
932
933   else /* dec, else would have begun with 0x or 0 */
934   {
935     base[1] = SC_0; base[0] = SC_A;
936   }
937
938   /* begin string evaluation, from left to right */
939   while (len > 0)
940   {
941     switch (*str)
942     {
943       case 'f':
944       case 'e':
945       case 'd':
946       case 'c':
947       case 'b':
948       case 'a':
949         if (base[0] > SC_9 || base[1] > SC_0) /* (base > 10) */
950         {
951           val[0] = _digit((*str)-'a'+10);
952         }
953         else fail_char(orig_str, orig_len, *str, str-orig_str+1);
954         break;
955
956       case 'F':
957       case 'E':
958       case 'D':
959       case 'C':
960       case 'B':
961       case 'A':
962         if (base[0] > SC_9 || base[1] > SC_0) /* (base > 10) */
963         {
964           val[0] = _digit((*str)-'A'+10);
965         }
966         else fail_char(orig_str, orig_len, *str, str-orig_str+1);
967         break;
968
969       case '9':
970       case '8':
971         if (base[0] > SC_7 || base[1] > SC_0) /* (base > 8) */
972         {
973           val[0] = _digit((*str)-'0');
974         }
975         else fail_char(orig_str, orig_len, *str, str-orig_str+1);
976         break;
977
978       case '7':
979       case '6':
980       case '5':
981       case '4':
982       case '3':
983       case '2':
984       case '1':
985       case '0':
986         {
987           val[0] = _digit((*str)-'0');
988         }
989         break;
990
991       default:
992         fail_char(orig_str, orig_len, *str, str-orig_str+1);
993     } /* switch(*str) */
994
995     /* Radix conversion from base b to base B:
996      *  (UnUn-1...U1U0)b == ((((Un*b + Un-1)*b + ...)*b + U1)*b + U0)B */
997     _mul(base, calc_buffer, calc_buffer); /* multiply current value with base */
998     _add(val, calc_buffer, calc_buffer);  /* add next digit to current value  */
999
1000     /* get ready for the next letter */
1001     str++;
1002     len--;
1003
1004   } /* while (len > 0 ) */
1005
1006   if (sign)
1007   {
1008     _negate(calc_buffer, calc_buffer);
1009   }
1010 }
1011
1012 void sc_val_from_long(long value)
1013 {
1014   char *pos;
1015   int sign;
1016
1017   pos = calc_buffer;
1018   sign = (value < 0);
1019
1020   /* FIXME MININT won't work */
1021   if (sign) value = -value;
1022
1023   CLEAR_CALC_BUFFER();
1024
1025   while ((value != 0) && (pos < calc_buffer + CALC_BUFFER_SIZE))
1026   {
1027     *pos++ = _digit(value % 16);
1028     value /= 16;
1029   }
1030
1031   if (sign) _negate(calc_buffer, calc_buffer);
1032 }
1033
1034 long sc_val_to_long(const void *val)
1035 {
1036   int i;
1037   long l = 0;
1038
1039   for (i = CALC_BUFFER_SIZE - 1; i >= 0; i--)
1040   {
1041     l = (l << 4) + _val(((char *)val)[i]);
1042   }
1043   return l;
1044 }
1045
1046 void sc_min_from_bits(unsigned int num_bits, unsigned int sign)
1047 {
1048   char* pos;
1049   int i, bits;
1050
1051   CLEAR_CALC_BUFFER();
1052   if (!sign) return;  /* unsigned means minimum is 0(zero) */
1053
1054   pos = calc_buffer;
1055
1056   bits = num_bits - 1;
1057   for (i = 0; i < bits/4; i++)
1058     *pos++ = SC_0;
1059
1060   *pos++ = min_digit[bits%4];
1061
1062   for (i++; i <= CALC_BUFFER_SIZE - 1; i++)
1063     *pos++ = SC_F;
1064 }
1065
1066 void sc_max_from_bits(unsigned int num_bits, unsigned int sign)
1067 {
1068   char* pos;
1069   int i, bits;
1070
1071   CLEAR_CALC_BUFFER();
1072   pos = calc_buffer;
1073
1074   bits = num_bits - sign;
1075   for (i = 0; i < bits/4; i++)
1076     *pos++ = SC_F;
1077
1078   *pos++ = max_digit[bits%4];
1079
1080   for (i++; i <= CALC_BUFFER_SIZE - 1; i++)
1081     *pos++ = SC_0;
1082 }
1083
1084 void sc_calc(const void* value1, const void* value2, unsigned op)
1085 {
1086   char unused_res[CALC_BUFFER_SIZE]; /* temp buffer holding unused result of divmod */
1087
1088   const char *val1 = (const char *)value1;
1089   const char *val2 = (const char *)value2;
1090   CLEAR_CALC_BUFFER();
1091
1092   DEBUGPRINTF(("%s ", sc_print(value1, SC_HEX)));
1093
1094   switch (op)
1095   {
1096     case SC_NEG:
1097       _negate(val1, calc_buffer);
1098       DEBUGPRINTF(("negated: %s\n", sc_print_hex(calc_buffer)));
1099       return;
1100     case SC_OR:
1101       DEBUGPRINTF(("| "));
1102       _bitor(val1, val2, calc_buffer);
1103       break;
1104     case SC_AND:
1105       DEBUGPRINTF(("& "));
1106       _bitand(val1, val2, calc_buffer);
1107       break;
1108     case SC_XOR:
1109       DEBUGPRINTF(("^ "));
1110       _bitxor(val1, val2, calc_buffer);
1111       break;
1112     case SC_NOT:
1113       _bitnot(val1, calc_buffer);
1114       DEBUGPRINTF(("bit-negated: %s\n", sc_print_hex(calc_buffer)));
1115       return;
1116     case SC_ADD:
1117       DEBUGPRINTF(("+ "));
1118       _add(val1, val2, calc_buffer);
1119       break;
1120     case SC_SUB:
1121       DEBUGPRINTF(("- "));
1122       _sub(val1, val2, calc_buffer);
1123       break;
1124     case SC_MUL:
1125       DEBUGPRINTF(("* "));
1126       _mul(val1, val2, calc_buffer);
1127       break;
1128     case SC_DIV:
1129       DEBUGPRINTF(("/ "));
1130       _divmod(val1, val2, calc_buffer, unused_res);
1131       break;
1132     case SC_MOD:
1133       DEBUGPRINTF(("%% "));
1134       _divmod(val1, val2, unused_res, calc_buffer);
1135       break;
1136     default:
1137       assert(0);
1138   }
1139   DEBUGPRINTF(("%s -> ", sc_print_hex(value2)));
1140   DEBUGPRINTF(("%s\n", sc_print_hex(calc_buffer)));
1141 }
1142
1143 void sc_bitcalc(const void* value1, const void* value2, unsigned radius, unsigned sign, unsigned op)
1144 {
1145   const char *val1 = (const char *)value1;
1146   const char *val2 = (const char *)value2;
1147   CLEAR_CALC_BUFFER();
1148
1149   DEBUGPRINTF(("%s ", sc_print_hex(value1)));
1150   switch (op)
1151   {
1152     case SC_SHL:
1153       DEBUGPRINTF(("<< "));
1154       _shl(val1, val2, calc_buffer, radius, sign);
1155       break;
1156     case SC_SHR:
1157       DEBUGPRINTF((">> "));
1158       _shr(val1, val2, calc_buffer, radius, sign, 0);
1159       break;
1160     case SC_SHRS:
1161       DEBUGPRINTF((">>> "));
1162       _shr(val1, val2, calc_buffer, radius, sign, 1);
1163       break;
1164     case SC_ROT:
1165       DEBUGPRINTF(("<<>> "));
1166       _rot(val1, val2, calc_buffer, radius, sign);
1167       break;
1168     default:
1169       assert(0);
1170   }
1171   DEBUGPRINTF(("%s -> ", sc_print_hex(value2)));
1172   DEBUGPRINTF(("%s\n", sc_print_hex(calc_buffer)));
1173 }
1174
1175 int sc_comp(const void* value1, const void* value2)
1176 {
1177   int counter = CALC_BUFFER_SIZE - 1;
1178   const char *val1 = (const char *)value1;
1179   const char *val2 = (const char *)value2;
1180
1181   /* compare signs first:
1182    * the loop below can only compare values of the same sign! */
1183   if (_sign(val1) != _sign(val2)) return (_sign(val1) == 1)?(1):(-1);
1184
1185   /* loop until two digits differ, the values are equal if there
1186    * are no such two digits */
1187   while (val1[counter] == val2[counter])
1188   {
1189     counter--;
1190     if (counter < 0) return 0;
1191   }
1192
1193   /* the leftmost digit is the most significant, so this returns
1194    * the correct result.
1195    * This implies the digit enum is ordered */
1196   return (val1[counter] > val2[counter]) ? (1) : (-1);
1197 }
1198
1199 unsigned char sc_sub_bits(const void *value, int len, unsigned byte_ofs)
1200 {
1201   const char *val     = (const char *)value;
1202   unsigned nibble_ofs = 2 * byte_ofs;
1203   unsigned char res;
1204
1205   /* the current scheme uses one byte to store a nibble */
1206   if (nibble_ofs >= len)
1207     return 0;
1208
1209   res = _val(val[nibble_ofs]);
1210   if (len > nibble_ofs + 1)
1211     res |= _val(val[nibble_ofs + 1]) << 4;
1212
1213   return res;
1214 }
1215
1216 const char *sc_print(const void *value, unsigned base)
1217 {
1218   int counter;
1219
1220   const char *val = (const char *)value;
1221   char *pos;
1222   static char *buf = NULL;
1223
1224   if (buf != NULL) free(buf);
1225   buf = malloc(BIT_PATTERN_SIZE);
1226
1227   pos = buf + BIT_PATTERN_SIZE - 1;
1228   *pos = '\0';
1229
1230   switch (base)
1231   {
1232     case SC_HEX:
1233       for (counter = 0; counter < MAX_VALUE_SIZE; counter++)
1234       {
1235         if (val[counter] < SC_A)
1236           *(--pos) = val[counter] + '0';
1237         else
1238           *(--pos) = val[counter] + 'a' - 10;
1239       }
1240       break;
1241
1242     default:
1243       assert(0);
1244   }
1245   return pos;
1246 }