2 /*--------------------------------------------------------------------*/
3 /*--- Entirely standalone libc stuff. m_libcbase.c ---*/
4 /*--------------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2000-2013 Julian Seward
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 The GNU General Public License is contained in the file COPYING.
31 #include "pub_core_basics.h"
32 #include "pub_core_libcassert.h" // VG_(exit_now)
33 #include "pub_core_debuglog.h" // VG_(debugLog)
34 #include "pub_core_libcbase.h"
37 /* ---------------------------------------------------------------------
38 Assert machinery for use in this file. vg_assert cannot be called
39 here due to cyclic dependencies.
40 ------------------------------------------------------------------ */
42 #define libcbase_assert(expr) \
43 ((void) (LIKELY(expr) ? 0 : \
44 (ML_(libcbase_assert_fail)(#expr, \
46 __PRETTY_FUNCTION__))))
48 static void ML_(libcbase_assert_fail
)( const HChar
*expr
,
53 VG_(debugLog
)(0, "libcbase",
54 "Valgrind: FATAL: assertion failed:\n");
55 VG_(debugLog
)(0, "libcbase", " %s\n", expr
);
56 VG_(debugLog
)(0, "libcbase", " at %s:%d (%s)\n", file
, line
, fn
);
57 VG_(debugLog
)(0, "libcbase", "Exiting now.\n");
62 /* ---------------------------------------------------------------------
64 ------------------------------------------------------------------ */
66 Bool
VG_(isspace
) ( HChar c
)
68 return (c
== ' ' || c
== '\n' || c
== '\t' ||
69 c
== '\f' || c
== '\v' || c
== '\r');
72 Bool
VG_(isdigit
) ( HChar c
)
74 return (c
>= '0' && c
<= '9');
77 /* ---------------------------------------------------------------------
78 Converting strings to numbers
79 ------------------------------------------------------------------ */
81 static Bool
is_dec_digit(HChar c
, Long
* digit
)
83 if (c
>= '0' && c
<= '9') { *digit
= (Long
)(c
- '0'); return True
; }
87 static Bool
is_hex_digit(HChar c
, Long
* digit
)
89 if (c
>= '0' && c
<= '9') { *digit
= (Long
)(c
- '0'); return True
; }
90 if (c
>= 'A' && c
<= 'F') { *digit
= (Long
)((c
- 'A') + 10); return True
; }
91 if (c
>= 'a' && c
<= 'f') { *digit
= (Long
)((c
- 'a') + 10); return True
; }
95 Long
VG_(strtoll10
) ( const HChar
* str
, HChar
** endptr
)
97 Bool neg
= False
, converted
= False
;
98 Long n
= 0, digit
= 0;
99 const HChar
* str0
= str
;
101 // Skip leading whitespace.
102 while (VG_(isspace
)(*str
)) str
++;
104 // Allow a leading '-' or '+'.
105 if (*str
== '-') { str
++; neg
= True
; }
106 else if (*str
== '+') { str
++; }
108 while (is_dec_digit(*str
, &digit
)) {
109 converted
= True
; // Ok, we've actually converted a digit.
114 if (!converted
) str
= str0
; // If nothing converted, endptr points to
115 if (neg
) n
= -n
; // the start of the string.
117 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
121 ULong
VG_(strtoull10
) ( const HChar
* str
, HChar
** endptr
)
123 Bool converted
= False
;
126 const HChar
* str0
= str
;
128 // Skip leading whitespace.
129 while (VG_(isspace
)(*str
)) str
++;
131 // Allow a leading '+'.
132 if (*str
== '+') { str
++; }
134 while (is_dec_digit(*str
, &digit
)) {
135 converted
= True
; // Ok, we've actually converted a digit.
140 if (!converted
) str
= str0
; // If nothing converted, endptr points to
141 // the start of the string.
143 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
147 Long
VG_(strtoll16
) ( const HChar
* str
, HChar
** endptr
)
149 Bool neg
= False
, converted
= False
;
150 Long n
= 0, digit
= 0;
151 const HChar
* str0
= str
;
153 // Skip leading whitespace.
154 while (VG_(isspace
)(*str
)) str
++;
156 // Allow a leading '-' or '+'.
157 if (*str
== '-') { str
++; neg
= True
; }
158 else if (*str
== '+') { str
++; }
160 // Allow leading "0x", but only if there's a hex digit
163 && (*(str
+1) == 'x' || *(str
+1) == 'X')
164 && is_hex_digit( *(str
+2), &digit
)) {
168 while (is_hex_digit(*str
, &digit
)) {
169 converted
= True
; // Ok, we've actually converted a digit.
174 if (!converted
) str
= str0
; // If nothing converted, endptr points to
175 if (neg
) n
= -n
; // the start of the string.
177 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
181 ULong
VG_(strtoull16
) ( const HChar
* str
, HChar
** endptr
)
183 Bool converted
= False
;
186 const HChar
* str0
= str
;
188 // Skip leading whitespace.
189 while (VG_(isspace
)(*str
)) str
++;
191 // Allow a leading '+'.
192 if (*str
== '+') { str
++; }
194 // Allow leading "0x", but only if there's a hex digit
197 && (*(str
+1) == 'x' || *(str
+1) == 'X')
198 && is_hex_digit( *(str
+2), &digit
)) {
202 while (is_hex_digit(*str
, &digit
)) {
203 converted
= True
; // Ok, we've actually converted a digit.
208 if (!converted
) str
= str0
; // If nothing converted, endptr points to
209 // the start of the string.
211 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
215 double VG_(strtod
) ( const HChar
* str
, HChar
** endptr
)
219 double n
= 0, frac
= 0, x
= 0.1;
221 // Skip leading whitespace.
222 while (VG_(isspace
)(*str
)) str
++;
224 // Allow a leading '-' or '+'.
225 if (*str
== '-') { str
++; neg
= True
; }
226 else if (*str
== '+') { str
++; }
228 while (is_dec_digit(*str
, &digit
)) {
235 while (is_dec_digit(*str
, &digit
)) {
245 *endptr
= CONST_CAST(HChar
*,str
); // Record first failing character.
249 HChar
VG_(tolower
) ( HChar c
)
251 if ( c
>= 'A' && c
<= 'Z' ) {
252 return c
- 'A' + 'a';
258 /* ---------------------------------------------------------------------
260 ------------------------------------------------------------------ */
262 SizeT
VG_(strlen
) ( const HChar
* str
)
265 while (str
[i
] != 0) i
++;
269 HChar
* VG_(strcat
) ( HChar
* dest
, const HChar
* src
)
271 HChar
* dest_orig
= dest
;
272 while (*dest
) dest
++;
273 while (*src
) *dest
++ = *src
++;
278 HChar
* VG_(strncat
) ( HChar
* dest
, const HChar
* src
, SizeT n
)
280 HChar
* dest_orig
= dest
;
281 while (*dest
) dest
++;
282 while (*src
&& n
> 0) { *dest
++ = *src
++; n
--; }
287 HChar
* VG_(strpbrk
) ( const HChar
* s
, const HChar
* accpt
)
294 return CONST_CAST(HChar
*,s
);
300 HChar
* VG_(strcpy
) ( HChar
* dest
, const HChar
* src
)
302 HChar
* dest_orig
= dest
;
303 while (*src
) *dest
++ = *src
++;
308 HChar
* VG_(strncpy
) ( HChar
* dest
, const HChar
* src
, SizeT ndest
)
312 if (i
>= ndest
) return dest
; /* reached limit */
315 /* reached NUL; pad rest with zeroes as required */
316 while (i
< ndest
) dest
[i
++] = 0;
322 Int
VG_(strcmp
) ( const HChar
* s1
, const HChar
* s2
)
325 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
326 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
329 if (*s1
== 0) return 0;
335 Int
VG_(strcasecmp
) ( const HChar
* s1
, const HChar
* s2
)
338 UChar c1
= (UChar
)VG_(tolower
)(*s1
);
339 UChar c2
= (UChar
)VG_(tolower
)(*s2
);
340 if (c1
< c2
) return -1;
341 if (c1
> c2
) return 1;
344 if (c1
== 0) return 0;
350 Int
VG_(strncmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
354 if (n
>= nmax
) return 0;
355 if (*(const UChar
*)s1
< *(const UChar
*)s2
) return -1;
356 if (*(const UChar
*)s1
> *(const UChar
*)s2
) return 1;
359 if (*s1
== 0) return 0;
365 Int
VG_(strncasecmp
) ( const HChar
* s1
, const HChar
* s2
, SizeT nmax
)
371 if (n
>= nmax
) return 0;
372 c1
= (UChar
)VG_(tolower
)(*s1
);
373 c2
= (UChar
)VG_(tolower
)(*s2
);
374 if (c1
< c2
) return -1;
375 if (c1
> c2
) return 1;
378 if (c1
== 0) return 0;
384 HChar
* VG_(strstr
) ( const HChar
* haystack
, const HChar
* needle
)
387 if (haystack
== NULL
)
389 n
= VG_(strlen
)(needle
);
391 if (haystack
[0] == 0)
393 if (VG_(strncmp
)(haystack
, needle
, n
) == 0)
394 return CONST_CAST(HChar
*,haystack
);
399 HChar
* VG_(strcasestr
) ( const HChar
* haystack
, const HChar
* needle
)
402 if (haystack
== NULL
)
404 n
= VG_(strlen
)(needle
);
406 if (haystack
[0] == 0)
408 if (VG_(strncasecmp
)(haystack
, needle
, n
) == 0)
409 return CONST_CAST(HChar
*,haystack
);
414 HChar
* VG_(strchr
) ( const HChar
* s
, HChar c
)
417 if (*s
== c
) return CONST_CAST(HChar
*,s
);
418 if (*s
== 0) return NULL
;
423 HChar
* VG_(strrchr
) ( const HChar
* s
, HChar c
)
425 Int n
= VG_(strlen
)(s
);
427 if (s
[n
] == c
) return CONST_CAST(HChar
*,s
) + n
;
432 /* (code copied from glib then updated to valgrind types) */
435 VG_(strtok
) (HChar
*s
, const HChar
*delim
)
437 return VG_(strtok_r
) (s
, delim
, &olds
);
441 VG_(strtok_r
) (HChar
* s
, const HChar
* delim
, HChar
** saveptr
)
448 /* Scan leading delimiters. */
449 s
+= VG_(strspn (s
, delim
));
456 /* Find the end of the token. */
458 s
= VG_(strpbrk (token
, delim
));
460 /* This token finishes the string. */
461 *saveptr
= token
+ VG_(strlen
) (token
);
464 /* Terminate the token and make OLDS point past it. */
471 static Bool
isHex ( HChar c
)
473 return ((c
>= '0' && c
<= '9') ||
474 (c
>= 'a' && c
<= 'f') ||
475 (c
>= 'A' && c
<= 'F'));
478 static UInt
fromHex ( HChar c
)
480 if (c
>= '0' && c
<= '9')
481 return (UInt
)c
- (UInt
)'0';
482 if (c
>= 'a' && c
<= 'f')
483 return 10 + (UInt
)c
- (UInt
)'a';
484 if (c
>= 'A' && c
<= 'F')
485 return 10 + (UInt
)c
- (UInt
)'A';
487 // ??? need to vg_assert(0);
491 Bool
VG_(parse_Addr
) ( const HChar
** ppc
, Addr
* result
)
493 Int used
, limit
= 2 * sizeof(Addr
);
502 while (isHex(**ppc
)) {
503 // ??? need to vg_assert(d < fromHex(**ppc));
504 *result
= ((*result
) << 4) | fromHex(**ppc
);
507 if (used
> limit
) return False
;
514 Bool
VG_(parse_enum_set
) ( const HChar
*tokens
,
519 const SizeT tokens_len
= VG_(strlen
)(tokens
);
520 if (tokens_len
> 1000) return False
; /* "obviously invalid" */
521 HChar tok_tokens
[tokens_len
+1];
522 HChar
*tokens_saveptr
;
527 const SizeT input_len
= VG_(strlen
)(input
);
528 if (input_len
> 1000) return False
; /* "obviously invalid" */
529 HChar tok_input
[input_len
+1];
530 HChar
*input_saveptr
;
533 UInt known_words
= 0;
534 Bool seen_all_kw
= False
;
535 Bool seen_none_kw
= False
;
539 VG_(strcpy
) (tok_input
, input
);
540 for (input_word
= VG_(strtok_r
)(tok_input
, ",", &input_saveptr
);
542 input_word
= VG_(strtok_r
)(NULL
, ",", &input_saveptr
)) {
544 if (allow_all
&& 0 == VG_(strcmp
)(input_word
, "all")) {
547 } else if (0 == VG_(strcmp
)(input_word
, "none")) {
552 // Scan tokens + compute all_set. Do that even if all or none was
553 // recognised to have a correct value for all_set when exiting
554 // of the 'input' loop.
557 VG_(strcpy
) (tok_tokens
, tokens
);
558 for (token
= VG_(strtok_r
)(tok_tokens
, ",", &tokens_saveptr
);
560 token
= VG_(strtok_r
)(NULL
, ",", &tokens_saveptr
)) {
561 if (0 != VG_(strcmp
)(token
, "-")) {
562 if (0 == VG_(strcmp
)(input_word
, token
)) {
563 *enum_set
|= 1 << token_nr
;
566 all_set
|= 1 << token_nr
;
572 if (known_words
!= word_nr
)
573 return False
; // One or more input_words not recognised.
575 if (seen_none_kw
|| *enum_set
)
576 return False
; // mixing all with either none or a specific value.
578 } else if (seen_none_kw
) {
579 if (seen_all_kw
|| *enum_set
)
580 return False
; // mixing none with either all or a specific value.
583 // seen neither all or none, we must see at least one value
591 SizeT
VG_(strspn
) ( const HChar
* s
, const HChar
* accpt
)
595 for (p
= s
; *p
!= '\0'; ++p
) {
596 for (a
= accpt
; *a
!= '\0'; ++a
)
607 SizeT
VG_(strcspn
) ( const HChar
* s
, const HChar
* reject
)
611 if (VG_(strchr
) (reject
, *s
++) == NULL
)
620 /* ---------------------------------------------------------------------
622 ------------------------------------------------------------------ */
624 void* VG_(memcpy
) ( void *dest
, const void *src
, SizeT sz
)
626 const UChar
* s
= (const UChar
*)src
;
627 UChar
* d
= (UChar
*)dest
;
628 const UInt
* sI
= (const UInt
*)src
;
629 UInt
* dI
= (UInt
*)dest
;
631 if (VG_IS_4_ALIGNED(dI
) && VG_IS_4_ALIGNED(sI
)) {
651 s
= (const UChar
*)sI
;
655 /* If we're unlucky, the alignment constraints for the fast case
656 above won't apply, and we'll have to do it all here. Hence the
677 void* VG_(memmove
)(void *dest
, const void *src
, SizeT sz
)
683 for (i
= 0; i
< sz
; i
++) {
684 ((UChar
*)dest
)[i
] = ((const UChar
*)src
)[i
];
687 else if (dest
> src
) {
688 for (i
= 0; i
< sz
; i
++) {
689 ((UChar
*)dest
)[sz
-i
-1] = ((const UChar
*)src
)[sz
-i
-1];
695 void* VG_(memset
) ( void *destV
, Int c
, SizeT sz
)
701 while ((!VG_IS_4_ALIGNED(d
)) && sz
>= 1) {
732 Int
VG_(memcmp
) ( const void* s1
, const void* s2
, SizeT n
)
735 const UChar
*p1
= s1
;
736 const UChar
*p2
= s2
;
753 /* ---------------------------------------------------------------------
754 Misc useful functions
755 ------------------------------------------------------------------ */
757 /////////////////////////////////////////////////////////////
758 /////////////////////////////////////////////////////////////
759 /// begin Bentley-McIlroy style quicksort
760 /// See "Engineering a Sort Function". Jon L Bentley, M. Douglas
761 /// McIlroy. Software Practice and Experience Vol 23(11), Nov 1993.
763 #define BM_MIN(a, b) \
766 #define BM_SWAPINIT(a, es) \
767 swaptype = ((a-(Char*)0) | es) % sizeof(Word) ? 2 \
768 : es > (SizeT)sizeof(Word) ? 1 \
771 #define BM_EXCH(a, b, t) \
772 (t = a, a = b, b = t)
774 #define BM_SWAP(a, b) \
776 ? bm_swapfunc(a, b, es, swaptype) \
777 : (void)BM_EXCH(*(Word*)(a), *(Word*)(b), t)
779 #define BM_VECSWAP(a, b, n) \
780 if (n > 0) bm_swapfunc(a, b, n, swaptype)
782 #define BM_PVINIT(pv, pm) \
784 pv = a, BM_SWAP(pv, pm); \
786 pv = (Char*)&v, v = *(Word*)pm
788 static Char
* bm_med3 ( Char
* a
, Char
* b
, Char
* c
,
789 Int (*cmp
)(const void*, const void*) ) {
791 ? (cmp(b
, c
) < 0 ? b
: cmp(a
, c
) < 0 ? c
: a
)
792 : (cmp(b
, c
) > 0 ? b
: cmp(a
, c
) > 0 ? c
: a
);
795 static void bm_swapfunc ( Char
* a
, Char
* b
, SizeT n
, Int swaptype
)
799 for ( ; n
> 0; a
+= sizeof(Word
), b
+= sizeof(Word
),
801 BM_EXCH(*(Word
*)a
, *(Word
*)b
, t
);
804 for ( ; n
> 0; a
+= 1, b
+= 1, n
-= 1)
809 static void bm_qsort ( Char
* a
, SizeT n
, SizeT es
,
810 Int (*cmp
)(const void*, const void*) )
812 Char
*pa
, *pb
, *pc
, *pd
, *pl
, *pm
, *pn
, *pv
;
819 for (pm
= a
+ es
; pm
< a
+ n
*es
; pm
+= es
)
820 for (pl
= pm
; pl
> a
&& cmp(pl
-es
, pl
) > 0; pl
-= es
)
830 pl
= bm_med3(pl
, pl
+s
, pl
+2*s
, cmp
);
831 pm
= bm_med3(pm
-s
, pm
, pm
+s
, cmp
);
832 pn
= bm_med3(pn
-2*s
, pn
-s
, pn
, cmp
);
834 pm
= bm_med3(pl
, pm
, pn
, cmp
);
838 pc
= pd
= a
+ (n
-1)*es
;
840 while (pb
<= pc
&& (r
= cmp(pb
, pv
)) <= 0) {
841 if (r
== 0) { BM_SWAP(pa
, pb
); pa
+= es
; }
844 while (pc
>= pb
&& (r
= cmp(pc
, pv
)) >= 0) {
845 if (r
== 0) { BM_SWAP(pc
, pd
); pd
-= es
; }
854 s
= BM_MIN(pa
-a
, pb
-pa
); BM_VECSWAP(a
, pb
-s
, s
);
855 s
= BM_MIN(pd
-pc
, pn
-pd
-es
); BM_VECSWAP(pb
, pn
-s
, s
);
856 /* Now recurse. Do the smaller partition first with an explicit
857 recursion, then do the larger partition using a tail call.
858 Except we can't rely on gcc to implement a tail call in any sane
859 way, so simply jump back to the start. This guarantees stack
860 growth can never exceed O(log N) even in the worst case. */
865 bm_qsort(a
, s1
/es
, es
, cmp
);
868 /* bm_qsort(pn-s2, s2/es, es, cmp); */
869 a
= pn
-s2
; n
= s2
/es
; es
= es
; cmp
= cmp
;
874 bm_qsort(pn
-s2
, s2
/es
, es
, cmp
);
877 /* bm_qsort(a, s1/es, es, cmp); */
878 a
= a
; n
= s1
/es
; es
= es
; cmp
= cmp
;
891 /// end Bentley-McIlroy style quicksort
892 /////////////////////////////////////////////////////////////
893 /////////////////////////////////////////////////////////////
895 /* Returns the base-2 logarithm of x. Returns -1 if x is not a power
897 Int
VG_(log2
) ( UInt x
)
900 /* Any more than 32 and we overflow anyway... */
901 for (i
= 0; i
< 32; i
++) {
902 if ((1U << i
) == x
) return i
;
907 /* Ditto for 64 bit numbers. */
908 Int
VG_(log2_64
) ( ULong x
)
911 for (i
= 0; i
< 64; i
++) {
912 if ((1ULL << i
) == x
) return i
;
917 // Generic quick sort.
918 void VG_(ssort
)( void* base
, SizeT nmemb
, SizeT size
,
919 Int (*compar
)(const void*, const void*) )
921 bm_qsort(base
,nmemb
,size
,compar
);
925 // This random number generator is based on the one suggested in Kernighan
926 // and Ritchie's "The C Programming Language".
928 // A pseudo-random number generator returning a random UInt. If pSeed
929 // is NULL, it uses its own seed, which starts at zero. If pSeed is
930 // non-NULL, it uses and updates whatever pSeed points at.
932 UInt
VG_(random
)( /*MOD*/UInt
* pSeed
)
934 static UInt seed
= 0;
939 *pSeed
= (1103515245 * *pSeed
+ 12345);
944 /* The following Adler-32 checksum code is taken from zlib-1.2.3, which
945 has the following copyright notice. */
949 (C) 1995-2004 Jean-loup Gailly and Mark Adler
951 This software is provided 'as-is', without any express or implied
952 warranty. In no event will the authors be held liable for any damages
953 arising from the use of this software.
955 Permission is granted to anyone to use this software for any purpose,
956 including commercial applications, and to alter it and redistribute it
957 freely, subject to the following restrictions:
959 1. The origin of this software must not be misrepresented; you must not
960 claim that you wrote the original software. If you use this software
961 in a product, an acknowledgment in the product documentation would be
962 appreciated but is not required.
963 2. Altered source versions must be plainly marked as such, and must not be
964 misrepresented as being the original software.
965 3. This notice may not be removed or altered from any source distribution.
967 Jean-loup Gailly Mark Adler
968 jloup@gzip.org madler@alumni.caltech.edu
970 If you use the zlib library in a product, we would appreciate *not*
971 receiving lengthy legal documents to sign. The sources are provided
972 for free but without warranty of any kind. The library has been
973 entirely written by Jean-loup Gailly and Mark Adler; it does not
974 include third-party code.
976 If you redistribute modified sources, we would appreciate that you include
977 in the file ChangeLog history information documenting your changes. Please
978 read the FAQ for more information on the distribution of modified source
982 /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and
983 return the updated checksum. If buf is NULL, this function returns
984 the required initial value for the checksum. An Adler-32 checksum is
985 almost as reliable as a CRC32 but can be computed much faster. */
986 UInt
VG_(adler32
)( UInt adler
, const UChar
* buf
, UInt len
)
988 # define BASE 65521UL /* largest prime smaller than 65536 */
990 /* NMAX is the largest n such that
991 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
993 # define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
994 # define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
995 # define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
996 # define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
997 # define DO16(buf) DO8(buf,0); DO8(buf,8);
999 /* The zlib sources recommend this definition of MOD if the
1000 processor cannot do integer division in hardware. */
1003 if (a >= (BASE << 16)) a -= (BASE << 16); \
1004 if (a >= (BASE << 15)) a -= (BASE << 15); \
1005 if (a >= (BASE << 14)) a -= (BASE << 14); \
1006 if (a >= (BASE << 13)) a -= (BASE << 13); \
1007 if (a >= (BASE << 12)) a -= (BASE << 12); \
1008 if (a >= (BASE << 11)) a -= (BASE << 11); \
1009 if (a >= (BASE << 10)) a -= (BASE << 10); \
1010 if (a >= (BASE << 9)) a -= (BASE << 9); \
1011 if (a >= (BASE << 8)) a -= (BASE << 8); \
1012 if (a >= (BASE << 7)) a -= (BASE << 7); \
1013 if (a >= (BASE << 6)) a -= (BASE << 6); \
1014 if (a >= (BASE << 5)) a -= (BASE << 5); \
1015 if (a >= (BASE << 4)) a -= (BASE << 4); \
1016 if (a >= (BASE << 3)) a -= (BASE << 3); \
1017 if (a >= (BASE << 2)) a -= (BASE << 2); \
1018 if (a >= (BASE << 1)) a -= (BASE << 1); \
1019 if (a >= BASE) a -= BASE; \
1023 if (a >= (BASE << 4)) a -= (BASE << 4); \
1024 if (a >= (BASE << 3)) a -= (BASE << 3); \
1025 if (a >= (BASE << 2)) a -= (BASE << 2); \
1026 if (a >= (BASE << 1)) a -= (BASE << 1); \
1027 if (a >= BASE) a -= BASE; \
1033 /* split Adler-32 into component sums */
1034 sum2
= (adler
>> 16) & 0xffff;
1037 /* in case user likes doing a byte at a time, keep it fast */
1045 return adler
| (sum2
<< 16);
1048 /* initial Adler-32 value (deferred check for len == 1 speed) */
1052 /* in case short lengths are provided, keep it somewhat fast */
1060 MOD4(sum2
); /* only added so many BASE's */
1061 return adler
| (sum2
<< 16);
1064 /* do length NMAX blocks -- requires just one modulo operation */
1065 while (len
>= NMAX
) {
1067 n
= NMAX
/ 16; /* NMAX is divisible by 16 */
1069 DO16(buf
); /* 16 sums unrolled */
1076 /* do remaining bytes (less than NMAX, still just one modulo) */
1077 if (len
) { /* avoid modulos if none remaining */
1091 /* return recombined sums */
1092 return adler
| (sum2
<< 16);
1105 /*--------------------------------------------------------------------*/
1107 /*--------------------------------------------------------------------*/