summaryrefslogtreecommitdiff
path: root/examples/enough.c
diff options
context:
space:
mode:
authorMark Adler <madler@alumni.caltech.edu>2012-08-18 17:59:50 -0700
committerMark Adler <madler@alumni.caltech.edu>2012-08-18 18:07:26 -0700
commit17068938ce5544ec3728402abd39bf3c55aec113 (patch)
treee366e8de99ddad7b53231d27bb797bd608ccbfce /examples/enough.c
parent3d9df6ecf83a41a3990fbff5c276f854d158e8ad (diff)
downloadzlib-17068938ce5544ec3728402abd39bf3c55aec113.tar.gz
zlib-17068938ce5544ec3728402abd39bf3c55aec113.tar.bz2
zlib-17068938ce5544ec3728402abd39bf3c55aec113.zip
Avoid shift equal to bits in type (caused endless loop).
Also clean up comparisons between different types, and some odd indentation problems that showed up somehow. A new endless loop was introduced by the clang compiler, which apparently does odd things when the right operand of << is equal to or greater than the number of bits in the type. The C standard in fact states that the behavior of << is undefined in that case. The loop was rewritten to use single-bit shifts.
Diffstat (limited to '')
-rw-r--r--examples/enough.c39
1 files changed, 21 insertions, 18 deletions
diff --git a/examples/enough.c b/examples/enough.c
index c40410b..b991144 100644
--- a/examples/enough.c
+++ b/examples/enough.c
@@ -1,7 +1,7 @@
1/* enough.c -- determine the maximum size of inflate's Huffman code tables over 1/* enough.c -- determine the maximum size of inflate's Huffman code tables over
2 * all possible valid and complete Huffman codes, subject to a length limit. 2 * all possible valid and complete Huffman codes, subject to a length limit.
3 * Copyright (C) 2007, 2008 Mark Adler 3 * Copyright (C) 2007, 2008, 2012 Mark Adler
4 * Version 1.3 17 February 2008 Mark Adler 4 * Version 1.4 18 August 2012 Mark Adler
5 */ 5 */
6 6
7/* Version history: 7/* Version history:
@@ -14,6 +14,9 @@
14 1.3 17 Feb 2008 Add argument for initial root table size 14 1.3 17 Feb 2008 Add argument for initial root table size
15 Fix bug for initial root table size == max - 1 15 Fix bug for initial root table size == max - 1
16 Use a macro to compute the history index 16 Use a macro to compute the history index
17 1.4 18 Aug 2012 Avoid shifts more than bits in type (caused endless loop!)
18 Clean up comparisons of different types
19 Clean up code indentation
17 */ 20 */
18 21
19/* 22/*
@@ -236,8 +239,8 @@ local big_t count(int syms, int len, int left)
236 for (use = least; use <= most; use++) { 239 for (use = least; use <= most; use++) {
237 got = count(syms - use, len + 1, (left - use) << 1); 240 got = count(syms - use, len + 1, (left - use) << 1);
238 sum += got; 241 sum += got;
239 if (got == -1 || sum < got) /* overflow */ 242 if (got == (big_t)0 - 1 || sum < got) /* overflow */
240 return -1; 243 return (big_t)0 - 1;
241 } 244 }
242 245
243 /* verify that all recursive calls are productive */ 246 /* verify that all recursive calls are productive */
@@ -458,6 +461,7 @@ int main(int argc, char **argv)
458 int n; /* number of symbols to code for this run */ 461 int n; /* number of symbols to code for this run */
459 big_t got; /* return value of count() */ 462 big_t got; /* return value of count() */
460 big_t sum; /* accumulated number of codes over n */ 463 big_t sum; /* accumulated number of codes over n */
464 code_t word; /* for counting bits in code_t */
461 465
462 /* set up globals for cleanup() */ 466 /* set up globals for cleanup() */
463 code = NULL; 467 code = NULL;
@@ -466,19 +470,19 @@ int main(int argc, char **argv)
466 470
467 /* get arguments -- default to the deflate literal/length code */ 471 /* get arguments -- default to the deflate literal/length code */
468 syms = 286; 472 syms = 286;
469 root = 9; 473 root = 9;
470 max = 15; 474 max = 15;
471 if (argc > 1) { 475 if (argc > 1) {
472 syms = atoi(argv[1]); 476 syms = atoi(argv[1]);
473 if (argc > 2) { 477 if (argc > 2) {
474 root = atoi(argv[2]); 478 root = atoi(argv[2]);
475 if (argc > 3) 479 if (argc > 3)
476 max = atoi(argv[3]); 480 max = atoi(argv[3]);
477 } 481 }
478 } 482 }
479 if (argc > 4 || syms < 2 || root < 1 || max < 1) { 483 if (argc > 4 || syms < 2 || root < 1 || max < 1) {
480 fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n", 484 fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
481 stderr); 485 stderr);
482 return 1; 486 return 1;
483 } 487 }
484 488
@@ -487,18 +491,17 @@ int main(int argc, char **argv)
487 max = syms - 1; 491 max = syms - 1;
488 492
489 /* determine the number of bits in a code_t */ 493 /* determine the number of bits in a code_t */
490 n = 0; 494 for (n = 0, word = 1; word; n++, word <<= 1)
491 while (((code_t)1 << n) != 0) 495 ;
492 n++;
493 496
494 /* make sure that the calculation of most will not overflow */ 497 /* make sure that the calculation of most will not overflow */
495 if (max > n || syms - 2 >= (((code_t)0 - 1) >> (max - 1))) { 498 if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) {
496 fputs("abort: code length too long for internal types\n", stderr); 499 fputs("abort: code length too long for internal types\n", stderr);
497 return 1; 500 return 1;
498 } 501 }
499 502
500 /* reject impossible code requests */ 503 /* reject impossible code requests */
501 if (syms - 1 > ((code_t)1 << max) - 1) { 504 if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) {
502 fprintf(stderr, "%d symbols cannot be coded in %d bits\n", 505 fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
503 syms, max); 506 syms, max);
504 return 1; 507 return 1;
@@ -532,7 +535,7 @@ int main(int argc, char **argv)
532 for (n = 2; n <= syms; n++) { 535 for (n = 2; n <= syms; n++) {
533 got = count(n, 1, 2); 536 got = count(n, 1, 2);
534 sum += got; 537 sum += got;
535 if (got == -1 || sum < got) { /* overflow */ 538 if (got == (big_t)0 - 1 || sum < got) { /* overflow */
536 fputs("abort: can't count that high!\n", stderr); 539 fputs("abort: can't count that high!\n", stderr);
537 cleanup(); 540 cleanup();
538 return 1; 541 return 1;
@@ -556,9 +559,9 @@ int main(int argc, char **argv)
556 } 559 }
557 560
558 /* find and show maximum inflate table usage */ 561 /* find and show maximum inflate table usage */
559 if (root > max) /* reduce root to max length */ 562 if (root > max) /* reduce root to max length */
560 root = max; 563 root = max;
561 if (syms < ((code_t)1 << (root + 1))) 564 if ((code_t)syms < ((code_t)1 << (root + 1)))
562 enough(syms); 565 enough(syms);
563 else 566 else
564 puts("cannot handle minimum code lengths > root"); 567 puts("cannot handle minimum code lengths > root");