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