Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / tools / dumpscan / int64.c
1 /*
2 * CMUCS AFStools
3 * dumpscan - routines for scanning and manipulating AFS volume dumps
4 *
5 * Copyright (c) 1998 Carnegie Mellon University
6 * All Rights Reserved.
7 *
8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation.
13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 *
18 * Carnegie Mellon requests users of this software to return to
19 *
20 * Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU
21 * School of Computer Science
22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890
24 *
25 * any improvements or extensions that they make and grant Carnegie Mellon
26 * the rights to redistribute these changes.
27 */
28
29 /* int64.c - Support for 64-bit integers */
30
31 #include <stdio.h>
32 #include <string.h>
33 #include "intNN.h"
34
35 char *
36 hexify_int64(dt_uint64 * X, char *buf)
37 {
38 static char mybuf[17];
39
40 #ifdef NATIVE_UINT64
41 char c, *p;
42 dt_uint64 x = *X;
43
44 if (!buf)
45 buf = mybuf;
46 p = buf + 16;
47 *p-- = 0;
48 while (x && p >= buf) {
49 c = x & 0xf;
50 c += ((c < 10) ? '0' : 'a' - 10);
51 *p-- = c;
52 x >>= 4;
53 }
54 while (p >= buf)
55 *p-- = '0';
56
57 #else
58 if (!buf)
59 buf = mybuf;
60 sprintf(buf, "%08lx%08lx", (unsigned long)X->hi, (unsigned long)X->lo);
61 #endif
62
63 return buf;
64 }
65
66
67 #ifdef NATIVE_UINT64
68 char *
69 decimate_int64(dt_uint64 * X, char *buf)
70 {
71 static char mybuf[21];
72 char *p;
73 dt_uint64 x = *X;
74
75 if (!buf)
76 buf = mybuf;
77 p = buf + 21;
78 *--p = 0;
79 while (x && p > buf) {
80 *--p = ((x % 10) + '0');
81 x /= 10;
82 }
83 if (!*p)
84 *--p = '0';
85 return p;
86 }
87
88 #else
89 static char bitvals[64][21] = {
90 /* 1 */ "00000000000000000001",
91 /* 2 */ "00000000000000000002",
92 /* 4 */ "00000000000000000004",
93 /* 8 */ "00000000000000000008",
94 /* 10 */ "00000000000000000016",
95 /* 20 */ "00000000000000000032",
96 /* 40 */ "00000000000000000064",
97 /* 80 */ "00000000000000000128",
98 /* 100 */ "00000000000000000256",
99 /* 200 */ "00000000000000000512",
100 /* 400 */ "00000000000000001024",
101 /* 800 */ "00000000000000002048",
102 /* 1000 */ "00000000000000004096",
103 /* 2000 */ "00000000000000008192",
104 /* 4000 */ "00000000000000016384",
105 /* 8000 */ "00000000000000032768",
106 /* 10000 */ "00000000000000065536",
107 /* 20000 */ "00000000000000131072",
108 /* 40000 */ "00000000000000262144",
109 /* 80000 */ "00000000000000524288",
110 /* 100000 */ "00000000000001048576",
111 /* 200000 */ "00000000000002097152",
112 /* 400000 */ "00000000000004194304",
113 /* 800000 */ "00000000000008388608",
114 /* 1000000 */ "00000000000016777216",
115 /* 2000000 */ "00000000000033554432",
116 /* 4000000 */ "00000000000067108864",
117 /* 8000000 */ "00000000000134217728",
118 /* 10000000 */ "00000000000268435456",
119 /* 20000000 */ "00000000000536870912",
120 /* 40000000 */ "00000000001073741824",
121 /* 80000000 */ "00000000002147483648",
122 /* 100000000 */ "00000000004294967296",
123 /* 200000000 */ "00000000008589934592",
124 /* 400000000 */ "00000000017179869184",
125 /* 800000000 */ "00000000034359738368",
126 /* 1000000000 */ "00000000068719476736",
127 /* 2000000000 */ "00000000137438953472",
128 /* 4000000000 */ "00000000274877906944",
129 /* 8000000000 */ "00000000549755813888",
130 /* 10000000000 */ "00000001099511627776",
131 /* 20000000000 */ "00000002199023255552",
132 /* 40000000000 */ "00000004398046511104",
133 /* 80000000000 */ "00000008796093022208",
134 /* 100000000000 */ "00000017592186044416",
135 /* 200000000000 */ "00000035184372088832",
136 /* 400000000000 */ "00000070368744177664",
137 /* 800000000000 */ "00000140737488355328",
138 /* 1000000000000 */ "00000281474976710656",
139 /* 2000000000000 */ "00000562949953421312",
140 /* 4000000000000 */ "00001125899906842624",
141 /* 8000000000000 */ "00002251799813685248",
142 /* 10000000000000 */ "00004503599627370496",
143 /* 20000000000000 */ "00009007199254740992",
144 /* 40000000000000 */ "00018014398509481984",
145 /* 80000000000000 */ "00036028797018963968",
146 /* 100000000000000 */ "00072057594037927936",
147 /* 200000000000000 */ "00144115188075855872",
148 /* 400000000000000 */ "00288230376151711744",
149 /* 800000000000000 */ "00576460752303423488",
150 /* 1000000000000000 */ "01152921504606846976",
151 /* 2000000000000000 */ "02305843009213693952",
152 /* 4000000000000000 */ "04611686018427387904",
153 /* 8000000000000000 */ "09223372036854775808"
154 };
155
156
157 static void
158 prep_table(void)
159 {
160 int bit, digit;
161
162 if (bitvals[0][0] < '0')
163 return;
164 for (bit = 0; bit < 64; bit++)
165 for (digit = 0; digit < 20; digit++)
166 bitvals[bit][digit] -= '0';
167 }
168
169
170 static void
171 add_bit(int bit, char *answer)
172 {
173 int digit;
174
175 for (digit = 19; digit >= 0; digit--) {
176 answer[digit] += bitvals[bit][digit];
177 if (!digit)
178 break;
179 while (answer[digit] > 9) {
180 answer[digit] -= 10;
181 answer[digit - 1]++;
182 }
183 }
184 }
185
186
187 static void
188 decimate(unsigned long hi, unsigned long lo, char *answer)
189 {
190 unsigned long mask;
191 int bit, digit;
192
193 memset(answer, 0, 21);
194 for (bit = 0, mask = 1; bit < 32; bit++, mask <<= 1)
195 if (lo & mask)
196 add_bit(bit, answer);
197 for (bit = 0, mask = 1; bit < 32; bit++, mask <<= 1)
198 if (hi & mask)
199 add_bit(bit + 32, answer);
200
201 for (digit = 0; digit < 20; digit++)
202 answer[digit] += '0';
203 }
204
205 char *
206 decimate_int64(dt_uint64 * X, char *buf)
207 {
208 static char mybuf[21];
209 char *p;
210
211 prep_table();
212 if (!buf)
213 buf = mybuf;
214 decimate(X->hi, X->lo, buf);
215 for (p = buf; *p == '0'; p++);
216 return (*p) ? p : p - 1;
217 }
218
219 #endif /* NATIVE_UINT64 */
220
221
222 void
223 shift_int64(dt_uint64 * X, int bits)
224 {
225 #ifdef NATIVE_UINT64
226 if (bits < 0)
227 *X >>= (-bits);
228 else
229 *X <<= bits;
230 #else
231 if (bits < 0) {
232 bits = -bits;
233 if (bits >= 32) {
234 X->lo = ((X->hi & 0xffffffffL) >> (bits - 32));
235 X->hi = 0;
236 } else {
237 X->lo = ((X->lo & 0xffffffffL) >> bits)
238 | ((X->hi & ((1 << (32 - bits)) - 1)) << (32 - bits));
239 X->hi = ((X->hi & 0xffffffffL) >> bits);
240 }
241 } else {
242 if (bits >= 32) {
243 X->hi = ((X->lo & 0xffffffffL) << (bits - 32));
244 X->lo = 0;
245 } else {
246 X->hi = ((X->hi & 0xffffffffL) << bits)
247 | ((X->lo & (((1 << bits) - 1) << (32 - bits))) >>
248 (32 - bits));
249 X->lo = ((X->lo & 0xffffffffL) << bits);
250 }
251 }
252 #endif
253 }
254
255
256 #ifdef TEST_INT64
257
258 /** the rest of this is for testing the int64 suite **/
259
260 #ifdef NATIVE_UINT64
261
262 #define xize(x) #x
263 #define stringize(x) xize(x)
264 #define INT64_NAME stringize(unsigned NATIVE_UINT64)
265
266
267 #endif /* NATIVE_UINT64 */
268
269
270 void
271 verify_int64_size()
272 {
273 #ifdef NATIVE_UINT64
274 signed char testchar = -1;
275 unsigned int testint = (unsigned char)testchar;
276
277 printf("We think '%s' is a native 64-bit type\n", INT64_NAME);
278
279 if (testint != 0xff) {
280 printf("testint = 0x%x; should be 0xff\n", testint);
281 fprintf(stderr, "Hmm... char's are not 8 bits. That sucks!\n");
282 exit(-1);
283 }
284 printf("Looks like a char is 8 bits...\n");
285
286 if (sizeof(unsigned NATIVE_UINT64) != 8) {
287 printf("sizeof(%s) = %d; should be 8\n", INT64_NAME,
288 sizeof(unsigned NATIVE_UINT64));
289 fprintf(stderr, "Hey! You said a %s was 64-bits wide!\n",
290 INT64_NAME);
291 exit(-1);
292 }
293 printf("Yippee! We have a native 64-bit type (%s)\n\n", INT64_NAME);
294
295 #else /* !NATIVE_UINT64 */
296
297 printf("Using fake 64-bit integers...\n\n");
298 #endif /* NATIVE_UINT64 */
299 }
300
301
302 void
303 test_int64_constructs(void)
304 {
305 dt_uint64 x, y;
306 afs_uint32 hi, lo;
307 int failures = 0, pass;
308 char buf[17];
309
310 printf("Constructor/accessor tests:\n");
311 printf("Setting x := %s\n", INT64_TEST_STR);
312 mk64(x, INT64_TEST_HI, INT64_TEST_LO);
313
314 #ifdef NATIVE_UINT64
315 pass = (x == INT64_TEST_CONST);
316 hexify_int64(&x, buf);
317 printf("NATIVE mk64: x = 0x%16s %s\n", buf,
318 pass ? "PASSED" : "FAILED");
319 if (!pass)
320 failures++;
321 #else
322 pass = (x.hi == INT64_TEST_HI && x.lo == INT64_TEST_LO);
323 printf("FAKE mk64: x.hi = 0x%08lx x.lo = 0x%08lx %s\n", x.hi,
324 x.lo, pass ? "PASSED" : "FAILED");
325 if (!pass)
326 failures++;
327 #endif
328
329 pass = (hi64(x) == INT64_TEST_HI && lo64(x) == INT64_TEST_LO);
330 printf("hi64/lo64: hi64(x) = 0x%08lx lo64(x) = 0x%08lx %s\n", hi64(x),
331 lo64(x), pass ? "PASSED" : "FAILED");
332 if (!pass)
333 failures++;
334
335 ex64(x, hi, lo);
336 pass = (hi == INT64_TEST_HI && lo == INT64_TEST_LO);
337 printf("ex64: hi = 0x%08lx lo = 0x%08lx %s\n", hi, lo,
338 pass ? "PASSED" : "FAILED");
339 if (!pass)
340 failures++;
341
342 cp64(y, x);
343 pass = (hi64(y) == INT64_TEST_HI && lo64(y) == INT64_TEST_LO);
344 printf("cp64: hi64(y) = 0x%08lx lo64(y) = 0x%08lx %s\n", hi64(y),
345 lo64(y), pass ? "PASSED" : "FAILED");
346 if (!pass)
347 failures++;
348
349 if (failures)
350 printf("%d/4 tests FAILED\n\n", failures);
351 else
352 printf("All 4 tests PASSED\n\n");
353 }
354
355
356 void
357 test_int64_compares()
358 {
359 #define NCOMPARE 9
360 dt_uint64 control, test[NCOMPARE];
361 char cbuf[17], tbuf[17];
362 int i, r, result[NCOMPARE];
363 int pass, failures, FAILURES = 0;
364
365 printf("Comparison tests:\n");
366
367 mk64(control, 0x12345678, 0xabcdabcd);
368 mk64(test[0], 0x12340000, 0xabcd0000);
369 result[0] = +1;
370 mk64(test[1], 0x12340000, 0xabcdabcd);
371 result[1] = +1;
372 mk64(test[2], 0x12340000, 0xabcdffff);
373 result[2] = +1;
374 mk64(test[3], 0x12345678, 0xabcd0000);
375 result[3] = +1;
376 mk64(test[4], 0x12345678, 0xabcdabcd);
377 result[4] = 0;
378 mk64(test[5], 0x12345678, 0xabcdffff);
379 result[5] = -1;
380 mk64(test[6], 0x1234ffff, 0xabcd0000);
381 result[6] = -1;
382 mk64(test[7], 0x1234ffff, 0xabcdabcd);
383 result[7] = -1;
384 mk64(test[8], 0x1234ffff, 0xabcdffff);
385 result[8] = -1;
386
387 for (i = 0; i < NCOMPARE; i++) {
388 failures = 0;
389 hexify_int64(&control, cbuf);
390 hexify_int64(&test[i], tbuf);
391
392 r = eq64(control, test[i]);
393 pass = (r == (result[i] == 0));
394 if (!pass)
395 failures++;
396 printf("0x%s == 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
397
398 r = ne64(control, test[i]);
399 pass = (r == (result[i] != 0));
400 if (!pass)
401 failures++;
402 printf("0x%s != 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
403
404 r = lt64(control, test[i]);
405 pass = (r == (result[i] < 0));
406 if (!pass)
407 failures++;
408 printf("0x%s < 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
409
410 r = le64(control, test[i]);
411 pass = (r == (result[i] <= 0));
412 if (!pass)
413 failures++;
414 printf("0x%s <= 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
415
416 r = gt64(control, test[i]);
417 pass = (r == (result[i] > 0));
418 if (!pass)
419 failures++;
420 printf("0x%s > 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
421
422 r = ge64(control, test[i]);
423 pass = (r == (result[i] >= 0));
424 if (!pass)
425 failures++;
426 printf("0x%s >= 0x%s %s\n", cbuf, tbuf, pass ? "PASSED" : "FAILED");
427
428 r = zero64(test[i]);
429 pass = !r;
430 if (!pass)
431 failures++;
432 printf("0x%s is nonzero %s\n", tbuf,
433 pass ? "PASSED" : "FAILED");
434
435 if (failures)
436 printf("%d/7 tests on this pair FAILED\n\n", failures);
437 else
438 printf("All 7 tests on this pair PASSED\n\n");
439 }
440
441 mk64(control, 0, 0);
442 pass = zero64(control);
443 if (!pass)
444 FAILURES++;
445 printf("0x0000000000000000 is zero %s\n",
446 pass ? "PASSED" : "FAILED");
447
448 if (FAILURES)
449 printf("%d/%d comparison tests FAILED\n\n", FAILURES,
450 7 * NCOMPARE + 1);
451 else
452 printf("All %d comparison tests PASSED\n\n", 7 * NCOMPARE + 1);
453 }
454
455
456 void
457 test_int64_arith()
458 {
459 printf("No arithmetic tests yet!!!\n");
460 }
461
462
463 void
464 main()
465 {
466 verify_int64_size();
467 test_int64_constructs();
468 test_int64_compares();
469 test_int64_arith();
470 exit(0);
471 }
472 #endif