diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:01:38 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2020-01-02 21:01:38 +0100 |
commit | f7d30133221896638f7bf4f66c504255c4b14f48 (patch) | |
tree | 5f3e07a049f388a3a309a615b8884318f6668a98 /nsprpub/pr/src/misc | |
parent | 26b297510a11758727438df4669357a2a2bc42ce (diff) | |
download | UXP-f7d30133221896638f7bf4f66c504255c4b14f48.tar UXP-f7d30133221896638f7bf4f66c504255c4b14f48.tar.gz UXP-f7d30133221896638f7bf4f66c504255c4b14f48.tar.lz UXP-f7d30133221896638f7bf4f66c504255c4b14f48.tar.xz UXP-f7d30133221896638f7bf4f66c504255c4b14f48.zip |
Issue #1338 - Part 1: Update NSPR to 4.24
Diffstat (limited to 'nsprpub/pr/src/misc')
-rw-r--r-- | nsprpub/pr/src/misc/dtoa.c | 6650 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/pralarm.c | 65 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/pratom.c | 215 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/praton.c | 87 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prcountr.c | 211 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prdtoa.c | 5042 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prenv.c | 68 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prerr.c | 156 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prerror.c | 21 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prerrortable.c | 94 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prinit.c | 216 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prinrval.c | 12 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/pripc.c | 2 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/pripcsem.c | 12 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prlong.c | 355 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prnetdb.c | 1301 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prolock.c | 30 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prrng.c | 16 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prsystem.c | 141 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prthinfo.c | 29 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prtime.c | 1978 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prtpool.c | 1919 | ||||
-rw-r--r-- | nsprpub/pr/src/misc/prtrace.c | 369 |
23 files changed, 9920 insertions, 9069 deletions
diff --git a/nsprpub/pr/src/misc/dtoa.c b/nsprpub/pr/src/misc/dtoa.c index c39e8925e..43883aba2 100644 --- a/nsprpub/pr/src/misc/dtoa.c +++ b/nsprpub/pr/src/misc/dtoa.c @@ -18,13 +18,13 @@ ***************************************************************/ /* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ + * with " at " changed at "@" and " dot " changed to "."). */ /* On a machine with IEEE extended-precision registers, it is * necessary to specify double-precision (53-bit) rounding precision * before invoking strtod or dtoa. If the machine uses (the equivalent * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); + * _control87(PC_53, MCW_PC); * does this with many compilers. Whether this or another call is * appropriate depends on the compiler; for this to work, it may be * necessary to #include "float.h" or another system-dependent header @@ -43,146 +43,146 @@ * * Modifications: * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). */ /* * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. + * significant byte has the lowest address. * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. + * significant byte has the lowest address. * #define Long int on machines with 32-bit ints and 64-bit longs. * #define IBM for IBM mainframe-style floating-point arithmetic. * #define VAX for VAX-style floating-point arithmetic (D_floating). * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. This will cause dtoa modes 4 and 5 to be - * treated the same as modes 2 and 3 for some inputs. + * computation of dtoa. This will cause dtoa modes 4 and 5 to be + * treated the same as modes 2 and 3 for some inputs. * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS - * is also #defined, fegetround() will be queried for the rounding mode. - * Note that both FLT_ROUNDS and fegetround() are specified by the C99 - * standard (and are specified to be consistent, with fesetround() - * affecting the value of FLT_ROUNDS), but that some (Linux) systems - * do not work correctly in this regard, so using fegetround() is more - * portable than using FLT_ROUNDS directly. + * and strtod and dtoa should round accordingly. Unless Trust_FLT_ROUNDS + * is also #defined, fegetround() will be queried for the rounding mode. + * Note that both FLT_ROUNDS and fegetround() are specified by the C99 + * standard (and are specified to be consistent, with fesetround() + * affecting the value of FLT_ROUNDS), but that some (Linux) systems + * do not work correctly in this regard, so using fegetround() is more + * portable than using FLT_ROUNDS directly. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. + * and Honor_FLT_ROUNDS is not #defined. * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. * #define ROUND_BIASED for IEEE-format with biased rounding and arithmetic - * that rounds toward +Infinity. + * that rounds toward +Infinity. * #define ROUND_BIASED_without_Round_Up for IEEE-format with biased - * rounding when the underlying floating-point arithmetic uses - * unbiased rounding. This prevent using ordinary floating-point - * arithmetic when the result could be computed with one rounding error. + * rounding when the underlying floating-point arithmetic uses + * unbiased rounding. This prevent using ordinary floating-point + * arithmetic when the result could be computed with one rounding error. * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. + * products but inaccurate quotients, e.g., for Intel i860. * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. * #define KR_headers for old-style C function headers. * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. Similarly, if you - * want something other than the system's free() to be called to - * recycle memory acquired from MALLOC, #define FREE to be the - * name of the alternate routine. (FREE or free is only called in - * pathological cases, e.g., in a dtoa call after a dtoa return in - * mode 3 with thousands of digits requested.) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a dtoa call after a dtoa return in + * mode 3 with thousands of digits requested.) * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. The longest string dtoa can return is about 751 bytes + * long. For conversions by strtod of strings of 800 digits and + * all dtoa conversions in single-threaded executions with 8-byte + * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte + * pointers, PRIVATE_MEM >= 7112 appears adequate. * #define NO_INFNAN_CHECK if you do not wish to have INFNAN_CHECK - * #defined automatically on IEEE systems. On such systems, - * when INFNAN_CHECK is #defined, strtod checks - * for Infinity and NaN (case insensitively). On some systems - * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. + * #defined automatically on IEEE systems. On such systems, + * when INFNAN_CHECK is #defined, strtod checks + * for Infinity and NaN (case insensitively). On some systems + * (e.g., some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. * #define USE_LOCALE to use the current locale's decimal_point value. * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. + * the result overflows to +-Infinity or underflows to 0. * #define NO_HEX_FP to omit recognition of hexadecimal floating-point - * values by strtod. + * values by strtod. * #define NO_STRTOD_BIGCOMP (on IEEE-arithmetic systems only for now) - * to disable logic for "fast" testing of very long input strings - * to strtod. This testing proceeds by initially truncating the - * input string, then if necessary comparing the whole string with - * a decimal expansion to decide close cases. This logic is only - * used for input more than STRTOD_DIGLIM digits long (default 40). + * to disable logic for "fast" testing of very long input strings + * to strtod. This testing proceeds by initially truncating the + * input string, then if necessary comparing the whole string with + * a decimal expansion to decide close cases. This logic is only + * used for input more than STRTOD_DIGLIM digits long (default 40). */ #ifndef Long @@ -302,7 +302,10 @@ extern "C" { Exactly one of IEEE_8087, IEEE_MC68k, VAX, or IBM should be defined. #endif -typedef union { double d; ULong L[2]; } U; +typedef union { + double d; + ULong L[2]; +} U; #ifdef IEEE_8087 #define word0(x) (x)->L[1] @@ -370,7 +373,7 @@ extern int strtod_diglim; #define Int_max 14 #ifndef NO_IEEE_Scale #define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ +#ifdef Flush_Denorm /* debugging option */ #undef Sudden_Underflow #endif #endif @@ -411,7 +414,7 @@ extern int strtod_diglim; #define Emin (-260) #define Exp_1 0x41000000 #define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ #define Frac_mask 0xffffff #define Frac_mask1 0xffffff #define Bletch 4 @@ -487,8 +490,10 @@ extern double rnd_prod(double, double), rnd_quot(double, double); #endif typedef struct BCinfo BCinfo; - struct -BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; }; +struct + BCinfo { + int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflchk; +}; #ifdef KR_headers #define FFFFFFFF ((((unsigned long)0xffff)<<16)|(unsigned long)0xffff) @@ -506,7 +511,7 @@ BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflc * slower. Hence the default is now to store 32 bits per Long. */ #endif -#else /* long long available */ +#else /* long long available */ #ifndef Llong #define Llong long long #endif @@ -516,8 +521,8 @@ BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflc #endif /* NO_LONG_LONG */ #ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ #endif #define Kmax 7 @@ -525,946 +530,981 @@ BCinfo { int dp0, dp1, dplen, dsign, e0, inexact, nd, nd0, rounding, scale, uflc #ifdef __cplusplus extern "C" double strtod(const char *s00, char **se); extern "C" char *dtoa(double d, int mode, int ndigits, - int *decpt, int *sign, char **rve); + int *decpt, int *sign, char **rve); #endif - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; +struct + Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; - typedef struct Bigint Bigint; +typedef struct Bigint Bigint; - static Bigint *freelist[Kmax+1]; +static Bigint *freelist[Kmax+1]; - static Bigint * +static Bigint * Balloc #ifdef KR_headers - (k) int k; +(k) int k; #else - (int k) +(int k) #endif { - int x; - Bigint *rv; + int x; + Bigint *rv; #ifndef Omit_Private_Memory - unsigned int len; + unsigned int len; #endif - ACQUIRE_DTOA_LOCK(0); - /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ - /* but this case seems very unlikely. */ - if (k <= Kmax && (rv = freelist[k])) - freelist[k] = rv->next; - else { - x = 1 << k; + ACQUIRE_DTOA_LOCK(0); + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k])) { + freelist[k] = rv->next; + } + else { + x = 1 << k; #ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); #else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); - rv->sign = rv->wds = 0; - return rv; - } - - static void + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else { + rv = (Bigint*)MALLOC(len*sizeof(double)); + } +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; +} + +static void Bfree #ifdef KR_headers - (v) Bigint *v; +(v) Bigint *v; #else - (Bigint *v) +(Bigint *v) #endif { - if (v) { - if (v->k > Kmax) + if (v) { + if (v->k > Kmax) #ifdef FREE - FREE((void*)v); + FREE((void*)v); #else - free((void*)v); -#endif - else { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); - } - } - } + free((void*)v); +#endif + else { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } +} #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ y->wds*sizeof(Long) + 2*sizeof(int)) - static Bigint * +static Bigint * multadd #ifdef KR_headers - (b, m, a) Bigint *b; int m, a; +(b, m, a) Bigint *b; int m, a; #else - (Bigint *b, int m, int a) /* multiply by m and add a */ +(Bigint *b, int m, int a) /* multiply by m and add a */ #endif { - int i, wds; + int i, wds; #ifdef ULLong - ULong *x; - ULLong carry, y; + ULong *x; + ULLong carry, y; #else - ULong carry, *x, y; + ULong carry, *x, y; #ifdef Pack_32 - ULong xi, z; + ULong xi, z; #endif #endif - Bigint *b1; + Bigint *b1; - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { #ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = y & FFFFFFFF; + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & FFFFFFFF; #else #ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); #else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif -#endif - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = carry; - b->wds = wds; - } - return b; - } - - static Bigint * + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; +} + +static Bigint * s2b #ifdef KR_headers - (s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; +(s, nd0, nd, y9, dplen) CONST char *s; int nd0, nd, dplen; ULong y9; #else - (const char *s, int nd0, int nd, ULong y9, int dplen) +(const char *s, int nd0, int nd, ULong y9, int dplen) #endif { - Bigint *b; - int i, k; - Long x, y; + Bigint *b; + int i, k; + Long x, y; - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; #ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; #else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s += dplen; - } - else - s += dplen + 9; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + } + while(++i < nd0); + s += dplen; + } + else { + s += dplen + 9; + } + for(; i < nd; i++) { + b = multadd(b, 10, *s++ - '0'); + } + return b; +} + +static int hi0bits #ifdef KR_headers - (x) ULong x; +(x) ULong x; #else - (ULong x) +(ULong x) #endif { - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; - } - - static int + int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) { + return 32; + } + } + return k; +} + +static int lo0bits #ifdef KR_headers - (y) ULong *y; +(y) ULong *y; #else - (ULong *y) +(ULong *y) #endif { - int k; - ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; - return k; - } - - static Bigint * + int k; + ULong x = *y; + + if (x & 7) { + if (x & 1) { + return 0; + } + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) { + return 32; + } + } + *y = x; + return k; +} + +static Bigint * i2b #ifdef KR_headers - (i) int i; +(i) int i; #else - (int i) +(int i) #endif { - Bigint *b; + Bigint *b; - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; - } + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} - static Bigint * +static Bigint * mult #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; #ifdef ULLong - ULLong carry, z; + ULLong carry, z; #else - ULong carry, z; + ULong carry, z; #ifdef Pack_32 - ULong z2; -#endif -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) { + k++; + } + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) { + *x = 0; + } + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; #ifdef ULLong - for(; xb < xbe; xc0++) { - if ((y = *xb++)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = z & FFFFFFFF; - } - while(x < xae); - *xc = carry; - } - } + for(; xb < xbe; xc0++) { + if ((y = *xb++)) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & FFFFFFFF; + } + while(x < xae); + *xc = carry; + } + } #else #ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if (y = *xb >> 16) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } #else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static Bigint * + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint * pow5mult #ifdef KR_headers - (b, k) Bigint *b; int k; +(b, k) Bigint *b; int k; #else - (Bigint *b, int k) +(Bigint *b, int k) #endif { - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; - - if ((i = k & 3)) - b = multadd(b, p05[i-1], 0); - - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; + + if ((i = k & 3)) { + b = multadd(b, p05[i-1], 0); + } + + if (!(k >>= 2)) { + return b; + } + if (!(p5 = p5s)) { + /* first time */ #ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = p5s = i2b(625); - p5->next = 0; - } - FREE_DTOA_LOCK(1); + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); #else - p5 = p5s = i2b(625); - p5->next = 0; -#endif - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) { + break; + } + if (!(p51 = p5->next)) { #ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - FREE_DTOA_LOCK(1); + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); #else - p51 = p5->next = mult(p5,p5); - p51->next = 0; + p51 = p5->next = mult(p5,p5); + p51->next = 0; #endif - } - p5 = p51; - } - return b; - } + } + p5 = p51; + } + return b; +} - static Bigint * +static Bigint * lshift #ifdef KR_headers - (b, k) Bigint *b; int k; +(b, k) Bigint *b; int k; #else - (Bigint *b, int k) +(Bigint *b, int k) #endif { - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; #ifdef Pack_32 - n = k >> 5; + n = k >> 5; #else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) { + k1++; + } + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) { + *x1++ = 0; + } + x = b->x; + xe = x + b->wds; #ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if ((*x1 = z)) - ++n1; - } + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if ((*x1 = z)) { + ++n1; + } + } #else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } - - static int + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) { + ++n1; + } + } +#endif + else do { + *x1++ = *x++; + } + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int cmp #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - ULong *xa, *xa0, *xb, *xb0; - int i, j; + ULong *xa, *xa0, *xb, *xb0; + int i, j; - i = a->wds; - j = b->wds; + i = a->wds; + j = b->wds; #ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } - - static Bigint * + if (i > 1 && !a->x[i-1]) { + Bug("cmp called with a->x[a->wds-1] == 0"); + } + if (j > 1 && !b->x[j-1]) { + Bug("cmp called with b->x[b->wds-1] == 0"); + } +#endif + if (i -= j) { + return i; + } + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) { + return *xa < *xb ? -1 : 1; + } + if (xa <= xa0) { + break; + } + } + return 0; +} + +static Bigint * diff #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; #ifdef ULLong - ULLong borrow, y; + ULLong borrow, y; #else - ULong borrow, y; + ULong borrow, y; #ifdef Pack_32 - ULong z; -#endif -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else { + i = 0; + } + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; #ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } #else #ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } #else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) { + wa--; + } + c->wds = wa; + return c; +} + +static double ulp #ifdef KR_headers - (x) U *x; +(x) U *x; #else - (U *x) +(U *x) #endif { - Long L; - U u; + Long L; + U u; - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; #ifndef Avoid_Underflow #ifndef Sudden_Underflow - if (L > 0) { + if (L > 0) { #endif #endif #ifdef IBM - L |= Exp_msk1 >> 4; + L |= Exp_msk1 >> 4; #endif - word0(&u) = L; - word1(&u) = 0; + word0(&u) = L; + word1(&u) = 0; #ifndef Avoid_Underflow #ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(&u) = 0x80000 >> L; - word1(&u) = 0; - } - else { - word0(&u) = 0; - L -= Exp_shift; - word1(&u) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif - return dval(&u); - } - - static double + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(&u) = 0x80000 >> L; + word1(&u) = 0; + } + else { + word0(&u) = 0; + L -= Exp_shift; + word1(&u) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(&u); +} + +static double b2d #ifdef KR_headers - (a, e) Bigint *a; int *e; +(a, e) Bigint *a; int *e; #else - (Bigint *a, int *e) +(Bigint *a, int *e) #endif { - ULong *xa, *xa0, w, y, z; - int k; - U d; + ULong *xa, *xa0, w, y, z; + int k; + U d; #ifdef VAX - ULong d0, d1; + ULong d0, d1; #else #define d0 word0(&d) #define d1 word1(&d) #endif - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; #ifdef DEBUG - if (!y) Bug("zero y in b2d"); + if (!y) { + Bug("zero y in b2d"); + } #endif - k = hi0bits(y); - *e = 32 - k; + k = hi0bits(y); + *e = 32 - k; #ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> (Ebits - k); - w = xa > xa0 ? *--xa : 0; - d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> (32 - k); - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> (32 - k); - } - else { - d0 = Exp_1 | y; - d1 = z; - } + if (k < Ebits) { + d0 = Exp_1 | y >> (Ebits - k); + w = xa > xa0 ? *--xa : 0; + d1 = y << ((32-Ebits) + k) | w >> (Ebits - k); + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> (32 - k); + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> (32 - k); + } + else { + d0 = Exp_1 | y; + d1 = z; + } #else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif - ret_d: + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif +ret_d: #ifdef VAX - word0(&d) = d0 >> 16 | d0 << 16; - word1(&d) = d1 >> 16 | d1 << 16; + word0(&d) = d0 >> 16 | d0 << 16; + word1(&d) = d1 >> 16 | d1 << 16; #else #undef d0 #undef d1 #endif - return dval(&d); - } + return dval(&d); +} - static Bigint * +static Bigint * d2b #ifdef KR_headers - (d, e, bits) U *d; int *e, *bits; +(d, e, bits) U *d; int *e, *bits; #else - (U *d, int *e, int *bits) +(U *d, int *e, int *bits) #endif { - Bigint *b; - int de, k; - ULong *x, y, z; + Bigint *b; + int de, k; + ULong *x, y, z; #ifndef Sudden_Underflow - int i; + int i; #endif #ifdef VAX - ULong d0, d1; - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; + ULong d0, d1; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; #else #define d0 word0(d) #define d1 word1(d) #endif #ifdef Pack_32 - b = Balloc(1); + b = Balloc(1); #else - b = Balloc(2); + b = Balloc(2); #endif - x = b->x; + x = b->x; - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ #ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); + de = (int)(d0 >> Exp_shift); #ifndef IBM - z |= Exp_msk11; + z |= Exp_msk11; #endif #else - if ((de = (int)(d0 >> Exp_shift))) - z |= Exp_msk1; + if ((de = (int)(d0 >> Exp_shift))) { + z |= Exp_msk1; + } #endif #ifdef Pack_32 - if ((y = d1)) { - if ((k = lo0bits(&y))) { - x[0] = y | z << (32 - k); - z >>= k; - } - else - x[0] = y; + if ((y = d1)) { + if ((k = lo0bits(&y))) { + x[0] = y | z << (32 - k); + z >>= k; + } + else { + x[0] = y; + } #ifndef Sudden_Underflow - i = + i = #endif - b->wds = (x[1] = z) ? 2 : 1; - } - else { - k = lo0bits(&z); - x[0] = z; + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; #ifndef Sudden_Underflow - i = + i = #endif - b->wds = 1; - k += 32; - } + b->wds = 1; + k += 32; + } #else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { #ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; + if (!z) { + Bug("Zero passed to d2b"); + } +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) { + --i; + } + b->wds = i + 1; #endif #ifndef Sudden_Underflow - if (de) { + if (de) { #endif #ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); #else - *e = de - Bias - (P-1) + k; - *bits = P - k; + *e = de - Bias - (P-1) + k; + *bits = P - k; #endif #ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; + } + else { + *e = de - Bias - (P-1) + 1 + k; #ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); + *bits = 32*i - hi0bits(x[i-1]); #else - *bits = (i+2)*16 - hi0bits(x[i]); + *bits = (i+2)*16 - hi0bits(x[i]); #endif - } + } #endif - return b; - } + return b; +} #undef d0 #undef d1 - static double +static double ratio #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - U da, db; - int k, ka, kb; + U da, db; + int k, ka, kb; - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); + dval(&da) = b2d(a, &ka); + dval(&db) = b2d(b, &kb); #ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); + k = ka - kb + 32*(a->wds - b->wds); #else - k = ka - kb + 16*(a->wds - b->wds); + k = ka - kb + 16*(a->wds - b->wds); #endif #ifdef IBM - if (k > 0) { - word0(&da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&da) *= 1 << k; - } - else { - k = -k; - word0(&db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(&db) *= 1 << k; - } + if (k > 0) { + word0(&da) += (k >> 2)*Exp_msk1; + if (k &= 3) { + dval(&da) *= 1 << k; + } + } + else { + k = -k; + word0(&db) += (k >> 2)*Exp_msk1; + if (k &= 3) { + dval(&db) *= 1 << k; + } + } #else - if (k > 0) - word0(&da) += k*Exp_msk1; - else { - k = -k; - word0(&db) += k*Exp_msk1; - } -#endif - return dval(&da) / dval(&db); - } + if (k > 0) { + word0(&da) += k*Exp_msk1; + } + else { + k = -k; + word0(&db) += k*Exp_msk1; + } +#endif + return dval(&da) / dval(&db); +} - static CONST double +static CONST double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 #ifdef VAX - , 1e23, 1e24 + , 1e23, 1e24 #endif - }; +}; - static CONST double +static CONST double #ifdef IEEE_Arith bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, #ifdef Avoid_Underflow - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-256 */ + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-256 */ #else - 1e-256 + 1e-256 #endif - }; + }; /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ #define Scale_Bit 0x10 @@ -1497,19 +1537,20 @@ static CONST double tinytens[] = { 1e-16, 1e-32 }; #ifdef Need_Hexdig /*{*/ static unsigned char hexdig[256]; - static void +static void #ifdef KR_headers htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc; #else htinit(unsigned char *h, unsigned char *s, int inc) #endif { - int i, j; - for(i = 0; (j = s[i]) !=0; i++) - h[j] = i + inc; - } + int i, j; + for(i = 0; (j = s[i]) !=0; i++) { + h[j] = i + inc; + } +} - static void +static void #ifdef KR_headers hexdig_init() #else @@ -1517,10 +1558,10 @@ hexdig_init(void) #endif { #define USC (unsigned char *) - htinit(hexdig, USC "0123456789", 0x10); - htinit(hexdig, USC "abcdef", 0x10 + 10); - htinit(hexdig, USC "ABCDEF", 0x10 + 10); - } + htinit(hexdig, USC "0123456789", 0x10); + htinit(hexdig, USC "abcdef", 0x10 + 10); + htinit(hexdig, USC "ABCDEF", 0x10 + 10); +} #endif /* } Need_Hexdig */ #ifdef INFNAN_CHECK @@ -1533,94 +1574,102 @@ hexdig_init(void) #define NAN_WORD1 0 #endif - static int +static int match #ifdef KR_headers - (sp, t) char **sp, *t; +(sp, t) char **sp, *t; #else - (const char **sp, const char *t) +(const char **sp, const char *t) #endif { - int c, d; - CONST char *s = *sp; - - while((d = *t++)) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } + int c, d; + CONST char *s = *sp; + + while((d = *t++)) { + if ((c = *++s) >= 'A' && c <= 'Z') { + c += 'a' - 'A'; + } + if (c != d) { + return 0; + } + } + *sp = s + 1; + return 1; +} #ifndef No_Hex_NaN - static void +static void hexnan #ifdef KR_headers - (rvp, sp) U *rvp; CONST char **sp; +(rvp, sp) U *rvp; CONST char **sp; #else - (U *rvp, const char **sp) +(U *rvp, const char **sp) #endif { - ULong c, x[2]; - CONST char *s; - int c1, havedig, udx0, xshift; - - if (!hexdig['0']) - hexdig_init(); - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - /* allow optional initial 0x or 0X */ - while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') - ++s; - if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) - s += 2; - while((c = *(CONST unsigned char*)++s)) { - if ((c1 = hexdig[c])) - c = c1 & 0xf; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } + ULong c, x[2]; + CONST char *s; + int c1, havedig, udx0, xshift; + + if (!hexdig['0']) { + hexdig_init(); + } + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + /* allow optional initial 0x or 0X */ + while((c = *(CONST unsigned char*)(s+1)) && c <= ' ') { + ++s; + } + if (s[1] == '0' && (s[2] == 'x' || s[2] == 'X')) { + s += 2; + } + while((c = *(CONST unsigned char*)++s)) { + if ((c1 = hexdig[c])) { + c = c1 & 0xf; + } + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } #ifdef GDTOA_NON_PEDANTIC_NANCHECK - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else { + return; /* invalid form: don't change *sp */ + } #else - else { - do { - if (/*(*/ c == ')') { - *sp = s + 1; - break; - } - } while((c = *++s)); - break; - } -#endif - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(rvp) = Exp_mask | x[0]; - word1(rvp) = x[1]; - } - } + else { + do { + if (/*(*/ c == ')') { + *sp = s + 1; + break; + } + } while((c = *++s)); + break; + } +#endif + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) { + x[0] = (x[0] << 4) | (x[1] >> 28); + } + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(rvp) = Exp_mask | x[0]; + word1(rvp) = x[1]; + } +} #endif /*No_Hex_NaN*/ #endif /* INFNAN_CHECK */ @@ -1635,1956 +1684,2122 @@ hexnan #endif #if !defined(NO_HEX_FP) || defined(Honor_FLT_ROUNDS) /*{*/ - static Bigint * +static Bigint * #ifdef KR_headers increment(b) Bigint *b; #else increment(Bigint *b) #endif { - ULong *x, *xe; - Bigint *b1; - - x = b->x; - xe = x + b->wds; - do { - if (*x < (ULong)0xffffffffL) { - ++*x; - return b; - } - *x++ = 0; - } while(x < xe); - { - if (b->wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1,b); - Bfree(b); - b = b1; - } - b->x[b->wds++] = 1; - } - return b; - } + ULong *x, *xe; + Bigint *b1; + + x = b->x; + xe = x + b->wds; + do { + if (*x < (ULong)0xffffffffL) { + ++*x; + return b; + } + *x++ = 0; + } while(x < xe); + { + if (b->wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1,b); + Bfree(b); + b = b1; + } + b->x[b->wds++] = 1; + } + return b; +} #endif /*}*/ #ifndef NO_HEX_FP /*{*/ - static void +static void #ifdef KR_headers rshift(b, k) Bigint *b; int k; #else rshift(Bigint *b, int k) #endif { - ULong *x, *x1, *xe, y; - int n; - - x = x1 = b->x; - n = k >> kshift; - if (n < b->wds) { - xe = x + b->wds; - x += n; - if (k &= kmask) { - n = 32 - k; - y = *x++ >> k; - while(x < xe) { - *x1++ = (y | (*x << n)) & 0xffffffff; - y = *x++ >> k; - } - if ((*x1 = y) !=0) - x1++; - } - else - while(x < xe) - *x1++ = *x++; - } - if ((b->wds = x1 - b->x) == 0) - b->x[0] = 0; - } - - static ULong + ULong *x, *x1, *xe, y; + int n; + + x = x1 = b->x; + n = k >> kshift; + if (n < b->wds) { + xe = x + b->wds; + x += n; + if (k &= kmask) { + n = 32 - k; + y = *x++ >> k; + while(x < xe) { + *x1++ = (y | (*x << n)) & 0xffffffff; + y = *x++ >> k; + } + if ((*x1 = y) !=0) { + x1++; + } + } + else + while(x < xe) { + *x1++ = *x++; + } + } + if ((b->wds = x1 - b->x) == 0) { + b->x[0] = 0; + } +} + +static ULong #ifdef KR_headers any_on(b, k) Bigint *b; int k; #else any_on(Bigint *b, int k) #endif { - int n, nwds; - ULong *x, *x0, x1, x2; - - x = b->x; - nwds = b->wds; - n = k >> kshift; - if (n > nwds) - n = nwds; - else if (n < nwds && (k &= kmask)) { - x1 = x2 = x[n]; - x1 >>= k; - x1 <<= k; - if (x1 != x2) - return 1; - } - x0 = x; - x += n; - while(x > x0) - if (*--x) - return 1; - return 0; - } - -enum { /* rounding values: same as FLT_ROUNDS */ - Round_zero = 0, - Round_near = 1, - Round_up = 2, - Round_down = 3 - }; - - void + int n, nwds; + ULong *x, *x0, x1, x2; + + x = b->x; + nwds = b->wds; + n = k >> kshift; + if (n > nwds) { + n = nwds; + } + else if (n < nwds && (k &= kmask)) { + x1 = x2 = x[n]; + x1 >>= k; + x1 <<= k; + if (x1 != x2) { + return 1; + } + } + x0 = x; + x += n; + while(x > x0) + if (*--x) { + return 1; + } + return 0; +} + +enum { /* rounding values: same as FLT_ROUNDS */ + Round_zero = 0, + Round_near = 1, + Round_up = 2, + Round_down = 3 +}; + +void #ifdef KR_headers gethex(sp, rvp, rounding, sign) - CONST char **sp; U *rvp; int rounding, sign; +CONST char **sp; U *rvp; int rounding, sign; #else gethex( CONST char **sp, U *rvp, int rounding, int sign) #endif { - Bigint *b; - CONST unsigned char *decpt, *s0, *s, *s1; - Long e, e1; - ULong L, lostbits, *x; - int big, denorm, esign, havedig, k, n, nbits, up, zret; + Bigint *b; + CONST unsigned char *decpt, *s0, *s, *s1; + Long e, e1; + ULong L, lostbits, *x; + int big, denorm, esign, havedig, k, n, nbits, up, zret; #ifdef IBM - int j; + int j; #endif - enum { + enum { #ifdef IEEE_Arith /*{{*/ - emax = 0x7fe - Bias - P + 1, - emin = Emin - P + 1 + emax = 0x7fe - Bias - P + 1, + emin = Emin - P + 1 #else /*}{*/ - emin = Emin - P, + emin = Emin - P, #ifdef VAX - emax = 0x7ff - Bias - P + 1 + emax = 0x7ff - Bias - P + 1 #endif #ifdef IBM - emax = 0x7f - Bias - P + emax = 0x7f - Bias - P #endif #endif /*}}*/ - }; + }; #ifdef USE_LOCALE - int i; + int i; #ifdef NO_LOCALE_CACHE - const unsigned char *decimalpoint = (unsigned char*) - localeconv()->decimal_point; + const unsigned char *decimalpoint = (unsigned char*) + localeconv()->decimal_point; #else - const unsigned char *decimalpoint; - static unsigned char *decimalpoint_cache; - if (!(s0 = decimalpoint_cache)) { - s0 = (unsigned char*)localeconv()->decimal_point; - if ((decimalpoint_cache = (unsigned char*) - MALLOC(strlen((CONST char*)s0) + 1))) { - strcpy((char*)decimalpoint_cache, (CONST char*)s0); - s0 = decimalpoint_cache; - } - } - decimalpoint = s0; -#endif -#endif - - if (!hexdig['0']) - hexdig_init(); - havedig = 0; - s0 = *(CONST unsigned char **)sp + 2; - while(s0[havedig] == '0') - havedig++; - s0 += havedig; - s = s0; - decpt = 0; - zret = 0; - e = 0; - if (hexdig[*s]) - havedig++; - else { - zret = 1; + const unsigned char *decimalpoint; + static unsigned char *decimalpoint_cache; + if (!(s0 = decimalpoint_cache)) { + s0 = (unsigned char*)localeconv()->decimal_point; + if ((decimalpoint_cache = (unsigned char*) + MALLOC(strlen((CONST char*)s0) + 1))) { + strcpy((char*)decimalpoint_cache, (CONST char*)s0); + s0 = decimalpoint_cache; + } + } + decimalpoint = s0; +#endif +#endif + + if (!hexdig['0']) { + hexdig_init(); + } + havedig = 0; + s0 = *(CONST unsigned char **)sp + 2; + while(s0[havedig] == '0') { + havedig++; + } + s0 += havedig; + s = s0; + decpt = 0; + zret = 0; + e = 0; + if (hexdig[*s]) { + havedig++; + } + else { + zret = 1; #ifdef USE_LOCALE - for(i = 0; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; + for(i = 0; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) { + goto pcheck; + } + } + decpt = s += i; #else - if (*s != '.') - goto pcheck; - decpt = ++s; -#endif - if (!hexdig[*s]) - goto pcheck; - while(*s == '0') - s++; - if (hexdig[*s]) - zret = 0; - havedig = 1; - s0 = s; - } - while(hexdig[*s]) - s++; + if (*s != '.') { + goto pcheck; + } + decpt = ++s; +#endif + if (!hexdig[*s]) { + goto pcheck; + } + while(*s == '0') { + s++; + } + if (hexdig[*s]) { + zret = 0; + } + havedig = 1; + s0 = s; + } + while(hexdig[*s]) { + s++; + } #ifdef USE_LOCALE - if (*s == *decimalpoint && !decpt) { - for(i = 1; decimalpoint[i]; ++i) { - if (s[i] != decimalpoint[i]) - goto pcheck; - } - decpt = s += i; + if (*s == *decimalpoint && !decpt) { + for(i = 1; decimalpoint[i]; ++i) { + if (s[i] != decimalpoint[i]) { + goto pcheck; + } + } + decpt = s += i; #else - if (*s == '.' && !decpt) { - decpt = ++s; -#endif - while(hexdig[*s]) - s++; - }/*}*/ - if (decpt) - e = -(((Long)(s-decpt)) << 2); - pcheck: - s1 = s; - big = esign = 0; - switch(*s) { - case 'p': - case 'P': - switch(*++s) { - case '-': - esign = 1; - /* no break */ - case '+': - s++; - } - if ((n = hexdig[*s]) == 0 || n > 0x19) { - s = s1; - break; - } - e1 = n - 0x10; - while((n = hexdig[*++s]) !=0 && n <= 0x19) { - if (e1 & 0xf8000000) - big = 1; - e1 = 10*e1 + n - 0x10; - } - if (esign) - e1 = -e1; - e += e1; - } - *sp = (char*)s; - if (!havedig) - *sp = (char*)s0 - 1; - if (zret) - goto retz1; - if (big) { - if (esign) { + if (*s == '.' && !decpt) { + decpt = ++s; +#endif + while(hexdig[*s]) { + s++; + } + }/*}*/ + if (decpt) { + e = -(((Long)(s-decpt)) << 2); + } +pcheck: + s1 = s; + big = esign = 0; + switch(*s) { + case 'p': + case 'P': + switch(*++s) { + case '-': + esign = 1; + /* no break */ + case '+': + s++; + } + if ((n = hexdig[*s]) == 0 || n > 0x19) { + s = s1; + break; + } + e1 = n - 0x10; + while((n = hexdig[*++s]) !=0 && n <= 0x19) { + if (e1 & 0xf8000000) { + big = 1; + } + e1 = 10*e1 + n - 0x10; + } + if (esign) { + e1 = -e1; + } + e += e1; + } + *sp = (char*)s; + if (!havedig) { + *sp = (char*)s0 - 1; + } + if (zret) { + goto retz1; + } + if (big) { + if (esign) { #ifdef IEEE_Arith - switch(rounding) { - case Round_up: - if (sign) - break; - goto ret_tiny; - case Round_down: - if (!sign) - break; - goto ret_tiny; - } -#endif - goto retz; + switch(rounding) { + case Round_up: + if (sign) { + break; + } + goto ret_tiny; + case Round_down: + if (!sign) { + break; + } + goto ret_tiny; + } +#endif + goto retz; #ifdef IEEE_Arith - ret_tiny: +ret_tiny: #ifndef NO_ERRNO - errno = ERANGE; + errno = ERANGE; #endif - word0(rvp) = 0; - word1(rvp) = 1; - return; + word0(rvp) = 0; + word1(rvp) = 1; + return; #endif /* IEEE_Arith */ - } - switch(rounding) { - case Round_near: - goto ovfl1; - case Round_up: - if (!sign) - goto ovfl1; - goto ret_big; - case Round_down: - if (sign) - goto ovfl1; - goto ret_big; - } - ret_big: - word0(rvp) = Big0; - word1(rvp) = Big1; - return; - } - n = s1 - s0 - 1; - for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) - k++; - b = Balloc(k); - x = b->x; - n = 0; - L = 0; + } + switch(rounding) { + case Round_near: + goto ovfl1; + case Round_up: + if (!sign) { + goto ovfl1; + } + goto ret_big; + case Round_down: + if (sign) { + goto ovfl1; + } + goto ret_big; + } +ret_big: + word0(rvp) = Big0; + word1(rvp) = Big1; + return; + } + n = s1 - s0 - 1; + for(k = 0; n > (1 << (kshift-2)) - 1; n >>= 1) { + k++; + } + b = Balloc(k); + x = b->x; + n = 0; + L = 0; #ifdef USE_LOCALE - for(i = 0; decimalpoint[i+1]; ++i); + for(i = 0; decimalpoint[i+1]; ++i); #endif - while(s1 > s0) { + while(s1 > s0) { #ifdef USE_LOCALE - if (*--s1 == decimalpoint[i]) { - s1 -= i; - continue; - } + if (*--s1 == decimalpoint[i]) { + s1 -= i; + continue; + } #else - if (*--s1 == '.') - continue; -#endif - if (n == ULbits) { - *x++ = L; - L = 0; - n = 0; - } - L |= (hexdig[*s1] & 0x0f) << n; - n += 4; - } - *x++ = L; - b->wds = n = x - b->x; - n = ULbits*n - hi0bits(L); - nbits = Nbits; - lostbits = 0; - x = b->x; - if (n > nbits) { - n -= nbits; - if (any_on(b,n)) { - lostbits = 1; - k = n - 1; - if (x[k>>kshift] & 1 << (k & kmask)) { - lostbits = 2; - if (k > 0 && any_on(b,k)) - lostbits = 3; - } - } - rshift(b, n); - e += n; - } - else if (n < nbits) { - n = nbits - n; - b = lshift(b, n); - e -= n; - x = b->x; - } - if (e > Emax) { - ovfl: - Bfree(b); - ovfl1: + if (*--s1 == '.') { + continue; + } +#endif + if (n == ULbits) { + *x++ = L; + L = 0; + n = 0; + } + L |= (hexdig[*s1] & 0x0f) << n; + n += 4; + } + *x++ = L; + b->wds = n = x - b->x; + n = ULbits*n - hi0bits(L); + nbits = Nbits; + lostbits = 0; + x = b->x; + if (n > nbits) { + n -= nbits; + if (any_on(b,n)) { + lostbits = 1; + k = n - 1; + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits = 2; + if (k > 0 && any_on(b,k)) { + lostbits = 3; + } + } + } + rshift(b, n); + e += n; + } + else if (n < nbits) { + n = nbits - n; + b = lshift(b, n); + e -= n; + x = b->x; + } + if (e > Emax) { +ovfl: + Bfree(b); +ovfl1: #ifndef NO_ERRNO - errno = ERANGE; -#endif - word0(rvp) = Exp_mask; - word1(rvp) = 0; - return; - } - denorm = 0; - if (e < emin) { - denorm = 1; - n = emin - e; - if (n >= nbits) { + errno = ERANGE; +#endif + word0(rvp) = Exp_mask; + word1(rvp) = 0; + return; + } + denorm = 0; + if (e < emin) { + denorm = 1; + n = emin - e; + if (n >= nbits) { #ifdef IEEE_Arith /*{*/ - switch (rounding) { - case Round_near: - if (n == nbits && (n < 2 || any_on(b,n-1))) - goto ret_tiny; - break; - case Round_up: - if (!sign) - goto ret_tiny; - break; - case Round_down: - if (sign) - goto ret_tiny; - } + switch (rounding) { + case Round_near: + if (n == nbits && (n < 2 || any_on(b,n-1))) { + goto ret_tiny; + } + break; + case Round_up: + if (!sign) { + goto ret_tiny; + } + break; + case Round_down: + if (sign) { + goto ret_tiny; + } + } #endif /* } IEEE_Arith */ - Bfree(b); - retz: + Bfree(b); +retz: #ifndef NO_ERRNO - errno = ERANGE; -#endif - retz1: - rvp->d = 0.; - return; - } - k = n - 1; - if (lostbits) - lostbits = 1; - else if (k > 0) - lostbits = any_on(b,k); - if (x[k>>kshift] & 1 << (k & kmask)) - lostbits |= 2; - nbits -= n; - rshift(b,n); - e = emin; - } - if (lostbits) { - up = 0; - switch(rounding) { - case Round_zero: - break; - case Round_near: - if (lostbits & 2 - && (lostbits & 1) | (x[0] & 1)) - up = 1; - break; - case Round_up: - up = 1 - sign; - break; - case Round_down: - up = sign; - } - if (up) { - k = b->wds; - b = increment(b); - x = b->x; - if (denorm) { + errno = ERANGE; +#endif +retz1: + rvp->d = 0.; + return; + } + k = n - 1; + if (lostbits) { + lostbits = 1; + } + else if (k > 0) { + lostbits = any_on(b,k); + } + if (x[k>>kshift] & 1 << (k & kmask)) { + lostbits |= 2; + } + nbits -= n; + rshift(b,n); + e = emin; + } + if (lostbits) { + up = 0; + switch(rounding) { + case Round_zero: + break; + case Round_near: + if (lostbits & 2 + && (lostbits & 1) | (x[0] & 1)) { + up = 1; + } + break; + case Round_up: + up = 1 - sign; + break; + case Round_down: + up = sign; + } + if (up) { + k = b->wds; + b = increment(b); + x = b->x; + if (denorm) { #if 0 - if (nbits == Nbits - 1 - && x[nbits >> kshift] & 1 << (nbits & kmask)) - denorm = 0; /* not currently used */ -#endif - } - else if (b->wds > k - || ((n = nbits & kmask) !=0 - && hi0bits(x[k-1]) < 32-n)) { - rshift(b,1); - if (++e > Emax) - goto ovfl; - } - } - } + if (nbits == Nbits - 1 + && x[nbits >> kshift] & 1 << (nbits & kmask)) { + denorm = 0; /* not currently used */ + } +#endif + } + else if (b->wds > k + || ((n = nbits & kmask) !=0 + && hi0bits(x[k-1]) < 32-n)) { + rshift(b,1); + if (++e > Emax) { + goto ovfl; + } + } + } + } #ifdef IEEE_Arith - if (denorm) - word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; - else - word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); - word1(rvp) = b->x[0]; + if (denorm) { + word0(rvp) = b->wds > 1 ? b->x[1] & ~0x100000 : 0; + } + else { + word0(rvp) = (b->x[1] & ~0x100000) | ((e + 0x3ff + 52) << 20); + } + word1(rvp) = b->x[0]; #endif #ifdef IBM - if ((j = e & 3)) { - k = b->x[0] & ((1 << j) - 1); - rshift(b,j); - if (k) { - switch(rounding) { - case Round_up: - if (!sign) - increment(b); - break; - case Round_down: - if (sign) - increment(b); - break; - case Round_near: - j = 1 << (j-1); - if (k & j && ((k & (j-1)) | lostbits)) - increment(b); - } - } - } - e >>= 2; - word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); - word1(rvp) = b->x[0]; + if ((j = e & 3)) { + k = b->x[0] & ((1 << j) - 1); + rshift(b,j); + if (k) { + switch(rounding) { + case Round_up: + if (!sign) { + increment(b); + } + break; + case Round_down: + if (sign) { + increment(b); + } + break; + case Round_near: + j = 1 << (j-1); + if (k & j && ((k & (j-1)) | lostbits)) { + increment(b); + } + } + } + } + e >>= 2; + word0(rvp) = b->x[1] | ((e + 65 + 13) << 24); + word1(rvp) = b->x[0]; #endif #ifdef VAX - /* The next two lines ignore swap of low- and high-order 2 bytes. */ - /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ - /* word1(rvp) = b->x[0]; */ - word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); - word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); -#endif - Bfree(b); - } + /* The next two lines ignore swap of low- and high-order 2 bytes. */ + /* word0(rvp) = (b->x[1] & ~0x800000) | ((e + 129 + 55) << 23); */ + /* word1(rvp) = b->x[0]; */ + word0(rvp) = ((b->x[1] & ~0x800000) >> 16) | ((e + 129 + 55) << 7) | (b->x[1] << 16); + word1(rvp) = (b->x[0] >> 16) | (b->x[0] << 16); +#endif + Bfree(b); +} #endif /*!NO_HEX_FP}*/ - static int +static int #ifdef KR_headers dshift(b, p2) Bigint *b; int p2; #else dshift(Bigint *b, int p2) #endif { - int rv = hi0bits(b->x[b->wds-1]) - 4; - if (p2 > 0) - rv -= p2; - return rv & kmask; - } + int rv = hi0bits(b->x[b->wds-1]) - 4; + if (p2 > 0) { + rv -= p2; + } + return rv & kmask; +} - static int +static int quorem #ifdef KR_headers - (b, S) Bigint *b, *S; +(b, S) Bigint *b, *S; #else - (Bigint *b, Bigint *S) +(Bigint *b, Bigint *S) #endif { - int n; - ULong *bx, *bxe, q, *sx, *sxe; + int n; + ULong *bx, *bxe, q, *sx, *sxe; #ifdef ULLong - ULLong borrow, carry, y, ys; + ULLong borrow, carry, y, ys; #else - ULong borrow, carry, y, ys; + ULong borrow, carry, y, ys; #ifdef Pack_32 - ULong si, z, zs; + ULong si, z, zs; #endif #endif - n = S->wds; + n = S->wds; #ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ + /*debug*/ if (b->wds > n) + /*debug*/{ + Bug("oversize b in quorem"); + } +#endif + if (b->wds < n) { + return 0; + } + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ #ifdef DEBUG #ifdef NO_STRTOD_BIGCOMP - /*debug*/ if (q > 9) + /*debug*/ if (q > 9) #else - /* An oversized q is possible when quorem is called from bigcomp and */ - /* the input is near, e.g., twice the smallest denormalized number. */ - /*debug*/ if (q > 15) + /* An oversized q is possible when quorem is called from bigcomp and */ + /* the input is near, e.g., twice the smallest denormalized number. */ + /*debug*/ if (q > 15) #endif - /*debug*/ Bug("oversized quotient in quorem"); + /*debug*/ Bug("oversized quotient in quorem"); #endif - if (q) { - borrow = 0; - carry = 0; - do { + if (q) { + borrow = 0; + carry = 0; + do { #ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; #else #ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); #else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) { + --n; + } + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { #ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; #else #ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); #else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) { + --n; + } + b->wds = n; + } + } + return q; +} #if defined(Avoid_Underflow) || !defined(NO_STRTOD_BIGCOMP) /*{*/ - static double +static double sulp #ifdef KR_headers - (x, bc) U *x; BCinfo *bc; +(x, bc) U *x; BCinfo *bc; #else - (U *x, BCinfo *bc) +(U *x, BCinfo *bc) #endif { - U u; - double rv; - int i; - - rv = ulp(x); - if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) - return rv; /* Is there an example where i <= 0 ? */ - word0(&u) = Exp_1 + (i << Exp_shift); - word1(&u) = 0; - return rv * u.d; - } + U u; + double rv; + int i; + + rv = ulp(x); + if (!bc->scale || (i = 2*P + 1 - ((word0(x) & Exp_mask) >> Exp_shift)) <= 0) { + return rv; /* Is there an example where i <= 0 ? */ + } + word0(&u) = Exp_1 + (i << Exp_shift); + word1(&u) = 0; + return rv * u.d; +} #endif /*}*/ #ifndef NO_STRTOD_BIGCOMP - static void +static void bigcomp #ifdef KR_headers - (rv, s0, bc) - U *rv; CONST char *s0; BCinfo *bc; +(rv, s0, bc) +U *rv; CONST char *s0; BCinfo *bc; #else - (U *rv, const char *s0, BCinfo *bc) +(U *rv, const char *s0, BCinfo *bc) #endif { - Bigint *b, *d; - int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; - - dsign = bc->dsign; - nd = bc->nd; - nd0 = bc->nd0; - p5 = nd + bc->e0 - 1; - speccase = 0; + Bigint *b, *d; + int b2, bbits, d2, dd, dig, dsign, i, j, nd, nd0, p2, p5, speccase; + + dsign = bc->dsign; + nd = bc->nd; + nd0 = bc->nd0; + p5 = nd + bc->e0 - 1; + speccase = 0; #ifndef Sudden_Underflow - if (rv->d == 0.) { /* special case: value near underflow-to-zero */ - /* threshold was rounded to zero */ - b = i2b(1); - p2 = Emin - P + 1; - bbits = 1; + if (rv->d == 0.) { /* special case: value near underflow-to-zero */ + /* threshold was rounded to zero */ + b = i2b(1); + p2 = Emin - P + 1; + bbits = 1; #ifdef Avoid_Underflow - word0(rv) = (P+2) << Exp_shift; + word0(rv) = (P+2) << Exp_shift; #else - word1(rv) = 1; + word1(rv) = 1; #endif - i = 0; + i = 0; #ifdef Honor_FLT_ROUNDS - if (bc->rounding == 1) -#endif - { - speccase = 1; - --p2; - dsign = 0; - goto have_i; - } - } - else -#endif - b = d2b(rv, &p2, &bbits); + if (bc->rounding == 1) +#endif + { + speccase = 1; + --p2; + dsign = 0; + goto have_i; + } + } + else +#endif + b = d2b(rv, &p2, &bbits); #ifdef Avoid_Underflow - p2 -= bc->scale; + p2 -= bc->scale; #endif - /* floor(log2(rv)) == bbits - 1 + p2 */ - /* Check for denormal case. */ - i = P - bbits; - if (i > (j = P - Emin - 1 + p2)) { + /* floor(log2(rv)) == bbits - 1 + p2 */ + /* Check for denormal case. */ + i = P - bbits; + if (i > (j = P - Emin - 1 + p2)) { #ifdef Sudden_Underflow - Bfree(b); - b = i2b(1); - p2 = Emin; - i = P - 1; + Bfree(b); + b = i2b(1); + p2 = Emin; + i = P - 1; #ifdef Avoid_Underflow - word0(rv) = (1 + bc->scale) << Exp_shift; + word0(rv) = (1 + bc->scale) << Exp_shift; #else - word0(rv) = Exp_msk1; + word0(rv) = Exp_msk1; #endif - word1(rv) = 0; + word1(rv) = 0; #else - i = j; + i = j; #endif - } + } #ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (i > 0) - b = lshift(b, i); - if (dsign) - b = increment(b); - } - else -#endif - { - b = lshift(b, ++i); - b->x[0] |= 1; - } + if (bc->rounding != 1) { + if (i > 0) { + b = lshift(b, i); + } + if (dsign) { + b = increment(b); + } + } + else +#endif + { + b = lshift(b, ++i); + b->x[0] |= 1; + } #ifndef Sudden_Underflow - have_i: -#endif - p2 -= p5 + i; - d = i2b(1); - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - */ - if (p5 > 0) - d = pow5mult(d, p5); - else if (p5 < 0) - b = pow5mult(b, -p5); - if (p2 > 0) { - b2 = p2; - d2 = 0; - } - else { - b2 = 0; - d2 = -p2; - } - i = dshift(d, d2); - if ((b2 += i) > 0) - b = lshift(b, b2); - if ((d2 += i) > 0) - d = lshift(d, d2); - - /* Now b/d = exactly half-way between the two floating-point values */ - /* on either side of the input string. Compute first digit of b/d. */ - - if (!(dig = quorem(b,d))) { - b = multadd(b, 10, 0); /* very unlikely */ - dig = quorem(b,d); - } - - /* Compare b/d with s0 */ - - for(i = 0; i < nd0; ) { - if ((dd = s0[i++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - for(j = bc->dp1; i++ < nd;) { - if ((dd = s0[j++] - '0' - dig)) - goto ret; - if (!b->x[0] && b->wds == 1) { - if (i < nd) - dd = 1; - goto ret; - } - b = multadd(b, 10, 0); - dig = quorem(b,d); - } - if (b->x[0] || b->wds > 1 || dig > 0) - dd = -1; - ret: - Bfree(b); - Bfree(d); +have_i: +#endif + p2 -= p5 + i; + d = i2b(1); + /* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + */ + if (p5 > 0) { + d = pow5mult(d, p5); + } + else if (p5 < 0) { + b = pow5mult(b, -p5); + } + if (p2 > 0) { + b2 = p2; + d2 = 0; + } + else { + b2 = 0; + d2 = -p2; + } + i = dshift(d, d2); + if ((b2 += i) > 0) { + b = lshift(b, b2); + } + if ((d2 += i) > 0) { + d = lshift(d, d2); + } + + /* Now b/d = exactly half-way between the two floating-point values */ + /* on either side of the input string. Compute first digit of b/d. */ + + if (!(dig = quorem(b,d))) { + b = multadd(b, 10, 0); /* very unlikely */ + dig = quorem(b,d); + } + + /* Compare b/d with s0 */ + + for(i = 0; i < nd0; ) { + if ((dd = s0[i++] - '0' - dig)) { + goto ret; + } + if (!b->x[0] && b->wds == 1) { + if (i < nd) { + dd = 1; + } + goto ret; + } + b = multadd(b, 10, 0); + dig = quorem(b,d); + } + for(j = bc->dp1; i++ < nd;) { + if ((dd = s0[j++] - '0' - dig)) { + goto ret; + } + if (!b->x[0] && b->wds == 1) { + if (i < nd) { + dd = 1; + } + goto ret; + } + b = multadd(b, 10, 0); + dig = quorem(b,d); + } + if (b->x[0] || b->wds > 1 || dig > 0) { + dd = -1; + } +ret: + Bfree(b); + Bfree(d); #ifdef Honor_FLT_ROUNDS - if (bc->rounding != 1) { - if (dd < 0) { - if (bc->rounding == 0) { - if (!dsign) - goto retlow1; - } - else if (dsign) - goto rethi1; - } - else if (dd > 0) { - if (bc->rounding == 0) { - if (dsign) - goto rethi1; - goto ret1; - } - if (!dsign) - goto rethi1; - dval(rv) += 2.*sulp(rv,bc); - } - else { - bc->inexact = 0; - if (dsign) - goto rethi1; - } - } - else -#endif - if (speccase) { - if (dd <= 0) - rv->d = 0.; - } - else if (dd < 0) { - if (!dsign) /* does not happen for round-near */ + if (bc->rounding != 1) { + if (dd < 0) { + if (bc->rounding == 0) { + if (!dsign) { + goto retlow1; + } + } + else if (dsign) { + goto rethi1; + } + } + else if (dd > 0) { + if (bc->rounding == 0) { + if (dsign) { + goto rethi1; + } + goto ret1; + } + if (!dsign) { + goto rethi1; + } + dval(rv) += 2.*sulp(rv,bc); + } + else { + bc->inexact = 0; + if (dsign) { + goto rethi1; + } + } + } + else +#endif + if (speccase) { + if (dd <= 0) { + rv->d = 0.; + } + } + else if (dd < 0) { + if (!dsign) /* does not happen for round-near */ retlow1: - dval(rv) -= sulp(rv,bc); - } - else if (dd > 0) { - if (dsign) { - rethi1: - dval(rv) += sulp(rv,bc); - } - } - else { - /* Exact half-way case: apply round-even rule. */ - if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) { - i = 1 - j; - if (i <= 31) { - if (word1(rv) & (0x1 << i)) - goto odd; - } - else if (word0(rv) & (0x1 << (i-32))) - goto odd; - } - else if (word1(rv) & 1) { - odd: - if (dsign) - goto rethi1; - goto retlow1; - } - } + dval(rv) -= sulp(rv,bc); + } + else if (dd > 0) { + if (dsign) { +rethi1: + dval(rv) += sulp(rv,bc); + } + } + else { + /* Exact half-way case: apply round-even rule. */ + if ((j = ((word0(rv) & Exp_mask) >> Exp_shift) - bc->scale) <= 0) { + i = 1 - j; + if (i <= 31) { + if (word1(rv) & (0x1 << i)) { + goto odd; + } + } + else if (word0(rv) & (0x1 << (i-32))) { + goto odd; + } + } + else if (word1(rv) & 1) { +odd: + if (dsign) { + goto rethi1; + } + goto retlow1; + } + } #ifdef Honor_FLT_ROUNDS - ret1: +ret1: #endif - return; - } + return; +} #endif /* NO_STRTOD_BIGCOMP */ - double +double strtod #ifdef KR_headers - (s00, se) CONST char *s00; char **se; +(s00, se) CONST char *s00; char **se; #else - (const char *s00, char **se) +(const char *s00, char **se) #endif { - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; - int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1; - Long L; - U aadj2, adj, rv, rv0; - ULong y, z; - BCinfo bc; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, e, e1; + int esign, i, j, k, nd, nd0, nf, nz, nz0, nz1, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1; + Long L; + U aadj2, adj, rv, rv0; + ULong y, z; + BCinfo bc; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; #ifdef Avoid_Underflow - ULong Lsb, Lsb1; + ULong Lsb, Lsb1; #endif #ifdef SET_INEXACT - int oldinexact; + int oldinexact; #endif #ifndef NO_STRTOD_BIGCOMP - int req_bigcomp = 0; + int req_bigcomp = 0; #endif #ifdef Honor_FLT_ROUNDS /*{*/ #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - bc.rounding = Flt_Rounds; + bc.rounding = Flt_Rounds; #else /*}{*/ - bc.rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: bc.rounding = 0; break; - case FE_UPWARD: bc.rounding = 2; break; - case FE_DOWNWARD: bc.rounding = 3; - } + bc.rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: bc.rounding = 0; break; + case FE_UPWARD: bc.rounding = 2; break; + case FE_DOWNWARD: bc.rounding = 3; + } #endif /*}}*/ #endif /*}*/ #ifdef USE_LOCALE - CONST char *s2; -#endif - - sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0; - dval(&rv) = 0.; - for(s = s00;;s++) switch(*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - break2: - if (*s == '0') { + CONST char *s2; +#endif + + sign = nz0 = nz1 = nz = bc.dplen = bc.uflchk = 0; + dval(&rv) = 0.; + for(s = s00;; s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) { + goto break2; + } + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } +break2: + if (*s == '0') { #ifndef NO_HEX_FP /*{*/ - switch(s[1]) { - case 'x': - case 'X': + switch(s[1]) { + case 'x': + case 'X': #ifdef Honor_FLT_ROUNDS - gethex(&s, &rv, bc.rounding, sign); + gethex(&s, &rv, bc.rounding, sign); #else - gethex(&s, &rv, 1, sign); + gethex(&s, &rv, 1, sign); #endif - goto ret; - } + goto ret; + } #endif /*}*/ - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; - bc.dp0 = bc.dp1 = s - s0; - for(s1 = s; s1 > s0 && *--s1 == '0'; ) - ++nz1; + nz0 = 1; + while(*++s == '0') ; + if (!*s) { + goto ret; + } + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) { + y = 10*y + c - '0'; + } + else if (nd < 16) { + z = 10*z + c - '0'; + } + nd0 = nd; + bc.dp0 = bc.dp1 = s - s0; + for(s1 = s; s1 > s0 && *--s1 == '0'; ) { + ++nz1; + } #ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for(;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif - if (c == '.') { - c = *++s; - bc.dp1 = s - s0; - bc.dplen = bc.dp1 - bc.dp0; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - bc.dp0 = s0 - s; - bc.dp1 = bc.dp0 + bc.dplen; - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = nz1 = 0; - } - } - } - dig_done: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for(;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + c = *++s; + bc.dp1 = s - s0; + bc.dplen = bc.dp1 - bc.dp0; + if (!nd) { + for(; c == '0'; c = *++s) { + nz++; + } + if (c > '0' && c <= '9') { + bc.dp0 = s0 - s; + bc.dp1 = bc.dp0 + bc.dplen; + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { +have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) { + y *= 10; + } + else if (nd <= DBL_DIG + 1) { + z *= 10; + } + if (nd++ < 9) { + y = 10*y + c; + } + else if (nd <= DBL_DIG + 1) { + z = 10*z + c; + } + nz = nz1 = 0; + } + } + } +dig_done: + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') { + c = *++s; + } + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') { + L = 10*L + c - '0'; + } + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + { + e = 19999; /* safe for 16 bit ints */ + } + else { + e = (int)L; + } + if (esign) { + e = -e; + } + } + else { + e = 0; + } + } + else { + s = s00; + } + } + if (!nd) { + if (!nz && !nz0) { #ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - if (!bc.dplen) - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(&rv) = 0x7ff00000; - word1(&rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(&rv) = NAN_WORD0; - word1(&rv) = NAN_WORD1; + /* Check for Nan and Infinity */ + if (!bc.dplen) + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) { + ++s; + } + word0(&rv) = 0x7ff00000; + word1(&rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(&rv) = NAN_WORD0; + word1(&rv) = NAN_WORD1; #ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); + if (*s == '(') { /*)*/ + hexnan(&rv, &s); + } #endif - goto ret; - } - } + goto ret; + } + } #endif /* INFNAN_CHECK */ - ret0: - s = s00; - sign = 0; - } - goto ret; - } - bc.e0 = e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; - if (k > 9) { +ret0: + s = s00; + sign = 0; + } + goto ret; + } + bc.e0 = e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) { + nd0 = nd; + } + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(&rv) = y; + if (k > 9) { #ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); -#endif - dval(&rv) = tens[k - 9] * dval(&rv) + z; - } - bd0 = 0; - if (nd <= DBL_DIG + if (k > DBL_DIG) { + oldinexact = get_inexact(); + } +#endif + dval(&rv) = tens[k - 9] * dval(&rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG #ifndef RND_PRODQUOT #ifndef Honor_FLT_ROUNDS - && Flt_Rounds == 1 + && Flt_Rounds == 1 #endif #endif - ) { - if (!e) - goto ret; + ) { + if (!e) { + goto ret; + } #ifndef ROUND_BIASED_without_Round_Up - if (e > 0) { - if (e <= Ten_pmax) { + if (e > 0) { + if (e <= Ten_pmax) { #ifdef VAX - goto vax_ovfl_check; + goto vax_ovfl_check; #else #ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - /* rv = */ rounded_product(dval(&rv), tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(&rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ #ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } -#endif - e -= i; - dval(&rv) *= tens[i]; + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } +#endif + e -= i; + dval(&rv) *= tens[i]; #ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(&rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(&rv), tens[e]); - if ((word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(&rv) += P*Exp_msk1; + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ +vax_ovfl_check: + word0(&rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(&rv), tens[e]); + if ((word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + goto ovfl; + } + word0(&rv) += P*Exp_msk1; #else - /* rv = */ rounded_product(dval(&rv), tens[e]); + /* rv = */ rounded_product(dval(&rv), tens[e]); #endif - goto ret; - } - } + goto ret; + } + } #ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { + else if (e >= -Ten_pmax) { #ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv.d = -rv.d; - sign = 0; - } + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv.d = -rv.d; + sign = 0; + } #endif - /* rv = */ rounded_quotient(dval(&rv), tens[-e]); - goto ret; - } + /* rv = */ rounded_quotient(dval(&rv), tens[-e]); + goto ret; + } #endif #endif /* ROUND_BIASED_without_Round_Up */ - } - e1 += nd - k; + } + e1 += nd - k; #ifdef IEEE_Arith #ifdef SET_INEXACT - bc.inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); + bc.inexact = 1; + if (k <= DBL_DIG) { + oldinexact = get_inexact(); + } #endif #ifdef Avoid_Underflow - bc.scale = 0; + bc.scale = 0; #endif #ifdef Honor_FLT_ROUNDS - if (bc.rounding >= 2) { - if (sign) - bc.rounding = bc.rounding == 2 ? 0 : 2; - else - if (bc.rounding != 2) - bc.rounding = 0; - } + if (bc.rounding >= 2) { + if (sign) { + bc.rounding = bc.rounding == 2 ? 0 : 2; + } + else if (bc.rounding != 2) { + bc.rounding = 0; + } + } #endif #endif /*IEEE_Arith*/ - /* Get starting approximation = rv * 10**e1 */ + /* Get starting approximation = rv * 10**e1 */ - if (e1 > 0) { - if ((i = e1 & 15)) - dval(&rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: - /* Can't trust HUGE_VAL */ + if (e1 > 0) { + if ((i = e1 & 15)) { + dval(&rv) *= tens[i]; + } + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { +ovfl: + /* Can't trust HUGE_VAL */ #ifdef IEEE_Arith #ifdef Honor_FLT_ROUNDS - switch(bc.rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(&rv) = Big0; - word1(&rv) = Big1; - break; - default: - word0(&rv) = Exp_mask; - word1(&rv) = 0; - } + switch(bc.rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(&rv) = Big0; + word1(&rv) = Big1; + break; + default: + word0(&rv) = Exp_mask; + word1(&rv) = 0; + } #else /*Honor_FLT_ROUNDS*/ - word0(&rv) = Exp_mask; - word1(&rv) = 0; + word0(&rv) = Exp_mask; + word1(&rv) = 0; #endif /*Honor_FLT_ROUNDS*/ #ifdef SET_INEXACT - /* set overflow bit */ - dval(&rv0) = 1e300; - dval(&rv0) *= dval(&rv0); + /* set overflow bit */ + dval(&rv0) = 1e300; + dval(&rv0) *= dval(&rv0); #endif #else /*IEEE_Arith*/ - word0(&rv) = Big0; - word1(&rv) = Big1; + word0(&rv) = Big0; + word1(&rv) = Big1; #endif /*IEEE_Arith*/ - range_err: - if (bd0) { - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - } +range_err: + if (bd0) { + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(bd0); + Bfree(delta); + } #ifndef NO_ERRNO - errno = ERANGE; -#endif - goto ret; - } - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(&rv) -= P*Exp_msk1; - dval(&rv) *= bigtens[j]; - if ((z = word0(&rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(&rv) = Big0; - word1(&rv) = Big1; - } - else - word0(&rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15)) - dval(&rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; + errno = ERANGE; +#endif + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) { + dval(&rv) *= bigtens[j]; + } + /* The last multiplication could overflow. */ + word0(&rv) -= P*Exp_msk1; + dval(&rv) *= bigtens[j]; + if ((z = word0(&rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + goto ovfl; + } + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(&rv) = Big0; + word1(&rv) = Big1; + } + else { + word0(&rv) += P*Exp_msk1; + } + } + } + else if (e1 < 0) { + e1 = -e1; + if ((i = e1 & 15)) { + dval(&rv) /= tens[i]; + } + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) { + goto undfl; + } #ifdef Avoid_Underflow - if (e1 & Scale_Bit) - bc.scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; clear j low bits */ - if (j >= 32) { - if (j > 54) - goto undfl; - word1(&rv) = 0; - if (j >= 53) - word0(&rv) = (P+2)*Exp_msk1; - else - word0(&rv) &= 0xffffffff << (j-32); - } - else - word1(&rv) &= 0xffffffff << j; - } + if (e1 & Scale_Bit) { + bc.scale = 2*P; + } + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) { + dval(&rv) *= tinytens[j]; + } + if (bc.scale && (j = 2*P + 1 - ((word0(&rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; clear j low bits */ + if (j >= 32) { + if (j > 54) { + goto undfl; + } + word1(&rv) = 0; + if (j >= 53) { + word0(&rv) = (P+2)*Exp_msk1; + } + else { + word0(&rv) &= 0xffffffff << (j-32); + } + } + else { + word1(&rv) &= 0xffffffff << j; + } + } #else - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(&rv0) = dval(&rv); - dval(&rv) *= tinytens[j]; - if (!dval(&rv)) { - dval(&rv) = 2.*dval(&rv0); - dval(&rv) *= tinytens[j]; -#endif - if (!dval(&rv)) { - undfl: - dval(&rv) = 0.; - goto range_err; - } + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) { + dval(&rv) *= tinytens[j]; + } + /* The last multiplication could underflow. */ + dval(&rv0) = dval(&rv); + dval(&rv) *= tinytens[j]; + if (!dval(&rv)) { + dval(&rv) = 2.*dval(&rv0); + dval(&rv) *= tinytens[j]; +#endif + if (!dval(&rv)) { +undfl: + dval(&rv) = 0.; + goto range_err; + } #ifndef Avoid_Underflow - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif - } - } + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } +} - /* Now the hard part -- adjusting rv to the correct value.*/ +/* Now the hard part -- adjusting rv to the correct value.*/ - /* Put digits into bd: true value = bd * 10^e */ +/* Put digits into bd: true value = bd * 10^e */ - bc.nd = nd - nz1; +bc.nd = nd - nz1; #ifndef NO_STRTOD_BIGCOMP - bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ - /* to silence an erroneous warning about bc.nd0 */ - /* possibly not being initialized. */ - if (nd > strtod_diglim) { - /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ - /* minimum number of decimal digits to distinguish double values */ - /* in IEEE arithmetic. */ - i = j = 18; - if (i > nd0) - j += bc.dplen; - for(;;) { - if (--j < bc.dp1 && j >= bc.dp0) - j = bc.dp0 - 1; - if (s0[j] != '0') - break; - --i; - } - e += nd - i; - nd = i; - if (nd0 > nd) - nd0 = nd; - if (nd < 9) { /* must recompute y */ - y = 0; - for(i = 0; i < nd0; ++i) - y = 10*y + s0[i] - '0'; - for(j = bc.dp1; i < nd; ++i) - y = 10*y + s0[j++] - '0'; - } - } -#endif - bd0 = s2b(s0, nd0, nd, y, bc.dplen); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; +bc.nd0 = nd0; /* Only needed if nd > strtod_diglim, but done here */ +/* to silence an erroneous warning about bc.nd0 */ +/* possibly not being initialized. */ +if (nd > strtod_diglim) { + /* ASSERT(strtod_diglim >= 18); 18 == one more than the */ + /* minimum number of decimal digits to distinguish double values */ + /* in IEEE arithmetic. */ + i = j = 18; + if (i > nd0) { + j += bc.dplen; + } + for(;;) { + if (--j < bc.dp1 && j >= bc.dp0) { + j = bc.dp0 - 1; + } + if (s0[j] != '0') { + break; + } + --i; + } + e += nd - i; + nd = i; + if (nd0 > nd) { + nd0 = nd; + } + if (nd < 9) { /* must recompute y */ + y = 0; + for(i = 0; i < nd0; ++i) { + y = 10*y + s0[i] - '0'; + } + for(j = bc.dp1; i < nd; ++i) { + y = 10*y + s0[j++] - '0'; + } + } +} +#endif +bd0 = s2b(s0, nd0, nd, y, bc.dplen); + +for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(&rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) { + bb2 += bbe; + } + else { + bd2 -= bbe; + } + bs2 = bb2; #ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) - bs2++; + if (bc.rounding != 1) { + bs2++; + } #endif #ifdef Avoid_Underflow - Lsb = LSB; - Lsb1 = 0; - j = bbe - bc.scale; - i = j + bbbits - 1; /* logb(rv) */ - j = P + 1 - bbbits; - if (i < Emin) { /* denormal */ - i = Emin - i; - j -= i; - if (i < 32) - Lsb <<= i; - else if (i < 52) - Lsb1 = Lsb << (i-32); - else - Lsb1 = Exp_mask; - } + Lsb = LSB; + Lsb1 = 0; + j = bbe - bc.scale; + i = j + bbbits - 1; /* logb(rv) */ + j = P + 1 - bbbits; + if (i < Emin) { /* denormal */ + i = Emin - i; + j -= i; + if (i < 32) { + Lsb <<= i; + } + else if (i < 52) { + Lsb1 = Lsb << (i-32); + } + else { + Lsb1 = Exp_mask; + } + } #else /*Avoid_Underflow*/ #ifdef Sudden_Underflow #ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); #else - j = P + 1 - bbbits; + j = P + 1 - bbbits; #endif #else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) { /* denormal */ + j += P - Emin; + } + else { + j = P + 1 - bbbits; + } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - bb2 += j; - bd2 += j; + bb2 += j; + bd2 += j; #ifdef Avoid_Underflow - bd2 += bc.scale; -#endif - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - bc.dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); + bd2 += bc.scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) { + i = bs2; + } + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) { + bb = lshift(bb, bb2); + } + if (bd5 > 0) { + bd = pow5mult(bd, bd5); + } + if (bd2 > 0) { + bd = lshift(bd, bd2); + } + if (bs2 > 0) { + bs = lshift(bs, bs2); + } + delta = diff(bb, bd); + bc.dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); #ifndef NO_STRTOD_BIGCOMP /*{*/ - if (bc.nd > nd && i <= 0) { - if (bc.dsign) { - /* Must use bigcomp(). */ - req_bigcomp = 1; - break; - } + if (bc.nd > nd && i <= 0) { + if (bc.dsign) { + /* Must use bigcomp(). */ + req_bigcomp = 1; + break; + } #ifdef Honor_FLT_ROUNDS - if (bc.rounding != 1) { - if (i < 0) { - req_bigcomp = 1; - break; - } - } - else -#endif - i = -1; /* Discarded digits make delta smaller. */ - } + if (bc.rounding != 1) { + if (i < 0) { + req_bigcomp = 1; + break; + } + } + else +#endif + i = -1; /* Discarded digits make delta smaller. */ + } #endif /*}*/ #ifdef Honor_FLT_ROUNDS /*{*/ - if (bc.rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ + if (bc.rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ #ifdef SET_INEXACT - bc.inexact = 0; -#endif - break; - } - if (bc.rounding) { - if (bc.dsign) { - adj.d = 1.; - goto apply_adj; - } - } - else if (!bc.dsign) { - adj.d = -1.; - if (!word1(&rv) - && !(word0(&rv) & Frac_mask)) { - y = word0(&rv) & Exp_mask; + bc.inexact = 0; +#endif + break; + } + if (bc.rounding) { + if (bc.dsign) { + adj.d = 1.; + goto apply_adj; + } + } + else if (!bc.dsign) { + adj.d = -1.; + if (!word1(&rv) + && !(word0(&rv) & Frac_mask)) { + y = word0(&rv) & Exp_mask; #ifdef Avoid_Underflow - if (!bc.scale || y > 2*P*Exp_msk1) + if (!bc.scale || y > 2*P*Exp_msk1) #else - if (y) -#endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj.d = -0.5; - } - } - apply_adj: + if (y) +#endif + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) { + adj.d = -0.5; + } + } + } +apply_adj: #ifdef Avoid_Underflow /*{*/ - if (bc.scale && (y = word0(&rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; + if (bc.scale && (y = word0(&rv) & Exp_mask) + <= 2*P*Exp_msk1) { + word0(&adj) += (2*P+1)*Exp_msk1 - y; + } #else #ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= - P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - dval(&rv) += adj.d*ulp(dval(&rv)); - word0(&rv) -= P*Exp_msk1; - } - else + if ((word0(&rv) & Exp_mask) <= + P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + dval(&rv) += adj.d*ulp(dval(&rv)); + word0(&rv) -= P*Exp_msk1; + } + else #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow}*/ - dval(&rv) += adj.d*ulp(&rv); - } - break; - } - adj.d = ratio(delta, bs); - if (adj.d < 1.) - adj.d = 1.; - if (adj.d <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj.d; - if (y != adj.d) { - if (!((bc.rounding>>1) ^ bc.dsign)) - y++; - adj.d = y; - } - } + dval(&rv) += adj.d*ulp(&rv); + } + break; + } + adj.d = ratio(delta, bs); + if (adj.d < 1.) { + adj.d = 1.; + } + if (adj.d <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj.d; + if (y != adj.d) { + if (!((bc.rounding>>1) ^ bc.dsign)) { + y++; + } + adj.d = y; + } + } #ifdef Avoid_Underflow /*{*/ - if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(&adj) += (2*P+1)*Exp_msk1 - y; + if (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) { + word0(&adj) += (2*P+1)*Exp_msk1 - y; + } #else #ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - word0(&rv) += P*Exp_msk1; - adj.d *= ulp(dval(&rv)); - if (bc.dsign) - dval(&rv) += adj.d; - else - dval(&rv) -= adj.d; - word0(&rv) -= P*Exp_msk1; - goto cont; - } + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + word0(&rv) += P*Exp_msk1; + adj.d *= ulp(dval(&rv)); + if (bc.dsign) { + dval(&rv) += adj.d; + } + else { + dval(&rv) -= adj.d; + } + word0(&rv) -= P*Exp_msk1; + goto cont; + } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow}*/ - adj.d *= ulp(&rv); - if (bc.dsign) { - if (word0(&rv) == Big0 && word1(&rv) == Big1) - goto ovfl; - dval(&rv) += adj.d; - } - else - dval(&rv) -= adj.d; - goto cont; - } + adj.d *= ulp(&rv); + if (bc.dsign) { + if (word0(&rv) == Big0 && word1(&rv) == Big1) { + goto ovfl; + } + dval(&rv) += adj.d; + } + else { + dval(&rv) -= adj.d; + } + goto cont; + } #endif /*}Honor_FLT_ROUNDS*/ - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask #ifdef IEEE_Arith /*{*/ #ifdef Avoid_Underflow - || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + || (word0(&rv) & Exp_mask) <= (2*P+1)*Exp_msk1 #else - || (word0(&rv) & Exp_mask) <= Exp_msk1 + || (word0(&rv) & Exp_mask) <= Exp_msk1 #endif #endif /*}*/ - ) { + ) { #ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - bc.inexact = 0; -#endif - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ + if (!delta->x[0] && delta->wds <= 1) { + bc.inexact = 0; + } +#endif + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ #ifdef SET_INEXACT - bc.inexact = 0; -#endif - break; - } - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (bc.dsign) { - if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 - && word1(&rv) == ( + bc.inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) { + goto drop_down; + } + break; + } + if (i == 0) { + /* exactly half-way between */ + if (bc.dsign) { + if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 + && word1(&rv) == ( #ifdef Avoid_Underflow - (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : -#endif - 0xffffffff)) { - /*boundary case -- increment exponent*/ - if (word0(&rv) == Big0 && word1(&rv) == Big1) - goto ovfl; - word0(&rv) = (word0(&rv) & Exp_mask) - + Exp_msk1 + (bc.scale && (y = word0(&rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : +#endif + 0xffffffff)) { + /*boundary case -- increment exponent*/ + if (word0(&rv) == Big0 && word1(&rv) == Big1) { + goto ovfl; + } + word0(&rv) = (word0(&rv) & Exp_mask) + + Exp_msk1 #ifdef IBM - | Exp_msk1 >> 4 + | Exp_msk1 >> 4 #endif - ; - word1(&rv) = 0; + ; + word1(&rv) = 0; #ifdef Avoid_Underflow - bc.dsign = 0; -#endif - break; - } - } - else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { - drop_down: - /* boundary case -- decrement exponent */ + bc.dsign = 0; +#endif + break; + } + } + else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { +drop_down: + /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ - L = word0(&rv) & Exp_mask; + L = word0(&rv) & Exp_mask; #ifdef IBM - if (L < Exp_msk1) + if (L < Exp_msk1) #else #ifdef Avoid_Underflow - if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) + if (L <= (bc.scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) #else - if (L <= Exp_msk1) + if (L <= Exp_msk1) #endif /*Avoid_Underflow*/ #endif /*IBM*/ - { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - L -= Exp_msk1; + { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + L -= Exp_msk1; #else /*Sudden_Underflow}{*/ #ifdef Avoid_Underflow - if (bc.scale) { - L = word0(&rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - } + if (bc.scale) { + L = word0(&rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + { + break; + } + /* rv = smallest denormal */ + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + } #endif /*Avoid_Underflow*/ - L = (word0(&rv) & Exp_mask) - Exp_msk1; + L = (word0(&rv) & Exp_mask) - Exp_msk1; #endif /*Sudden_Underflow}}*/ - word0(&rv) = L | Bndry_mask1; - word1(&rv) = 0xffffffff; + word0(&rv) = L | Bndry_mask1; + word1(&rv) = 0xffffffff; #ifdef IBM - goto cont; + goto cont; #else #ifndef NO_STRTOD_BIGCOMP - if (bc.nd > nd) - goto cont; + if (bc.nd > nd) { + goto cont; + } #endif - break; + break; #endif - } + } #ifndef ROUND_BIASED #ifdef Avoid_Underflow - if (Lsb1) { - if (!(word0(&rv) & Lsb1)) - break; - } - else if (!(word1(&rv) & Lsb)) - break; + if (Lsb1) { + if (!(word0(&rv) & Lsb1)) { + break; + } + } + else if (!(word1(&rv) & Lsb)) { + break; + } #else - if (!(word1(&rv) & LSB)) - break; + if (!(word1(&rv) & LSB)) { + break; + } #endif #endif - if (bc.dsign) + if (bc.dsign) #ifdef Avoid_Underflow - dval(&rv) += sulp(&rv, &bc); + dval(&rv) += sulp(&rv, &bc); #else - dval(&rv) += ulp(&rv); + dval(&rv) += ulp(&rv); #endif #ifndef ROUND_BIASED - else { + else { #ifdef Avoid_Underflow - dval(&rv) -= sulp(&rv, &bc); + dval(&rv) -= sulp(&rv, &bc); #else - dval(&rv) -= ulp(&rv); + dval(&rv) -= ulp(&rv); #endif #ifndef Sudden_Underflow - if (!dval(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } -#endif - } + if (!dval(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } +#endif + } #ifdef Avoid_Underflow - bc.dsign = 1 - bc.dsign; + bc.dsign = 1 - bc.dsign; #endif #endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (bc.dsign) - aadj = aadj1 = 1.; - else if (word1(&rv) || word0(&rv) & Bndry_mask) { + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (bc.dsign) { + aadj = aadj1 = 1.; + } + else if (word1(&rv) || word0(&rv) & Bndry_mask) { #ifndef Sudden_Underflow - if (word1(&rv) == Tiny1 && !word0(&rv)) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = bc.dsign ? aadj : -aadj; + if (word1(&rv) == Tiny1 && !word0(&rv)) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) { + aadj = 1./FLT_RADIX; + } + else { + aadj *= 0.5; + } + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = bc.dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS - switch(bc.rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } + switch(bc.rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } #else - if (Flt_Rounds == 0) - aadj1 += 0.5; + if (Flt_Rounds == 0) { + aadj1 += 0.5; + } #endif /*Check_FLT_ROUNDS*/ - } - y = word0(&rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(&rv0) = dval(&rv); - word0(&rv) -= P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(&rv0) == Big0 && word1(&rv0) == Big1) - goto ovfl; - word0(&rv) = Big0; - word1(&rv) = Big1; - goto cont; - } - else - word0(&rv) += P*Exp_msk1; - } - else { + } + y = word0(&rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(&rv0) = dval(&rv); + word0(&rv) -= P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if ((word0(&rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(&rv0) == Big0 && word1(&rv0) == Big1) { + goto ovfl; + } + word0(&rv) = Big0; + word1(&rv) = Big1; + goto cont; + } + else { + word0(&rv) += P*Exp_msk1; + } + } + else { #ifdef Avoid_Underflow - if (bc.scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = aadj) <= 0) - z = 1; - aadj = z; - aadj1 = bc.dsign ? aadj : -aadj; - } - dval(&aadj2) = aadj1; - word0(&aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(&aadj2); - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if (rv.d == 0.) + if (bc.scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) { + z = 1; + } + aadj = z; + aadj1 = bc.dsign ? aadj : -aadj; + } + dval(&aadj2) = aadj1; + word0(&aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(&aadj2); + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + if (rv.d == 0.) #ifdef NO_STRTOD_BIGCOMP - goto undfl; + goto undfl; #else - { - if (bc.nd > nd) - bc.dsign = 1; - break; - } -#endif - } - else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } + { + if (bc.nd > nd) { + bc.dsign = 1; + } + break; + } +#endif + } + else { + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } #else #ifdef Sudden_Underflow - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { - dval(&rv0) = dval(&rv); - word0(&rv) += P*Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) { + dval(&rv0) = dval(&rv); + word0(&rv) += P*Exp_msk1; + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; #ifdef IBM - if ((word0(&rv) & Exp_mask) < P*Exp_msk1) + if ((word0(&rv) & Exp_mask) < P*Exp_msk1) #else - if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(&rv0) == Tiny0 - && word1(&rv0) == Tiny1) { - if (bc.nd >nd) { - bc.uflchk = 1; - break; - } - goto undfl; - } - word0(&rv) = Tiny0; - word1(&rv) = Tiny1; - goto cont; - } - else - word0(&rv) -= P*Exp_msk1; - } - else { - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } + if ((word0(&rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(&rv0) == Tiny0 + && word1(&rv0) == Tiny1) { + if (bc.nd >nd) { + bc.uflchk = 1; + break; + } + goto undfl; + } + word0(&rv) = Tiny0; + word1(&rv) = Tiny1; + goto cont; + } + else { + word0(&rv) -= P*Exp_msk1; + } + } + else { + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; + } #else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!bc.dsign) - aadj1 = -aadj1; - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!bc.dsign) { + aadj1 = -aadj1; + } + } + adj.d = aadj1 * ulp(&rv); + dval(&rv) += adj.d; #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - } - z = word0(&rv) & Exp_mask; + } + z = word0(&rv) & Exp_mask; #ifndef SET_INEXACT - if (bc.nd == nd) { + if (bc.nd == nd) { #ifdef Avoid_Underflow - if (!bc.scale) -#endif - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } - } -#endif - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); + if (!bc.scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (bc.dsign || word1(&rv) || word0(&rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) { + break; + } + } + else if (aadj < .4999999/FLT_RADIX) { + break; + } + } + } +#endif +cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); +} +Bfree(bb); +Bfree(bd); +Bfree(bs); +Bfree(bd0); +Bfree(delta); #ifndef NO_STRTOD_BIGCOMP - if (req_bigcomp) { - bd0 = 0; - bc.e0 += nz1; - bigcomp(&rv, s0, &bc); - y = word0(&rv) & Exp_mask; - if (y == Exp_mask) - goto ovfl; - if (y == 0 && rv.d == 0.) - goto undfl; - } +if (req_bigcomp) { + bd0 = 0; + bc.e0 += nz1; + bigcomp(&rv, s0, &bc); + y = word0(&rv) & Exp_mask; + if (y == Exp_mask) { + goto ovfl; + } + if (y == 0 && rv.d == 0.) { + goto undfl; + } +} #endif #ifdef SET_INEXACT - if (bc.inexact) { - if (!oldinexact) { - word0(&rv0) = Exp_1 + (70 << Exp_shift); - word1(&rv0) = 0; - dval(&rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); +if (bc.inexact) { + if (!oldinexact) { + word0(&rv0) = Exp_1 + (70 << Exp_shift); + word1(&rv0) = 0; + dval(&rv0) += 1.; + } +} +else if (!oldinexact) { + clear_inexact(); +} #endif #ifdef Avoid_Underflow - if (bc.scale) { - word0(&rv0) = Exp_1 - 2*P*Exp_msk1; - word1(&rv0) = 0; - dval(&rv) *= dval(&rv0); +if (bc.scale) { + word0(&rv0) = Exp_1 - 2*P*Exp_msk1; + word1(&rv0) = 0; + dval(&rv) *= dval(&rv0); #ifndef NO_ERRNO - /* try to avoid the bug of testing an 8087 register value */ + /* try to avoid the bug of testing an 8087 register value */ #ifdef IEEE_Arith - if (!(word0(&rv) & Exp_mask)) + if (!(word0(&rv) & Exp_mask)) #else - if (word0(&rv) == 0 && word1(&rv) == 0) + if (word0(&rv) == 0 && word1(&rv) == 0) #endif - errno = ERANGE; + errno = ERANGE; #endif - } +} #endif /* Avoid_Underflow */ #ifdef SET_INEXACT - if (bc.inexact && !(word0(&rv) & Exp_mask)) { - /* set underflow bit */ - dval(&rv0) = 1e-300; - dval(&rv0) *= dval(&rv0); - } -#endif - ret: - if (se) - *se = (char *)s; - return sign ? -dval(&rv) : dval(&rv); - } +if (bc.inexact && !(word0(&rv) & Exp_mask)) { + /* set underflow bit */ + dval(&rv0) = 1e-300; + dval(&rv0) *= dval(&rv0); +} +#endif +ret: +if (se) { + *se = (char *)s; +} +return sign ? -dval(&rv) : dval(&rv); +} #ifndef MULTIPLE_THREADS - static char *dtoa_result; +static char *dtoa_result; #endif - static char * +static char * #ifdef KR_headers rv_alloc(i) int i; #else rv_alloc(int i) #endif { - int j, k, *r; - - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; - j <<= 1) - k++; - r = (int*)Balloc(k); - *r = k; - return + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) { + k++; + } + r = (int*)Balloc(k); + *r = k; + return #ifndef MULTIPLE_THREADS - dtoa_result = + dtoa_result = #endif - (char *)(r+1); - } + (char *)(r+1); +} - static char * +static char * #ifdef KR_headers nrv_alloc(s, rve, n) char *s, **rve; int n; #else nrv_alloc(const char *s, char **rve, int n) #endif { - char *rv, *t; - - t = rv = rv_alloc(n); - while((*t = *s++)) t++; - if (rve) - *rve = t; - return rv; - } + char *rv, *t; + + t = rv = rv_alloc(n); + while((*t = *s++)) { + t++; + } + if (rve) { + *rve = t; + } + return rv; +} /* freedtoa(s) must be used to free values s returned by dtoa * when MULTIPLE_THREADS is #defined. It should be used in all cases, @@ -3592,21 +3807,22 @@ nrv_alloc(const char *s, char **rve, int n) * when MULTIPLE_THREADS is not defined. */ - void +void #ifdef KR_headers freedtoa(s) char *s; #else freedtoa(char *s) #endif { - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); #ifndef MULTIPLE_THREADS - if (s == dtoa_result) - dtoa_result = 0; + if (s == dtoa_result) { + dtoa_result = 0; + } #endif - } +} /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * @@ -3614,743 +3830,781 @@ freedtoa(char *s) * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. * * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. */ - char * +char * dtoa #ifdef KR_headers - (dd, mode, ndigits, decpt, sign, rve) - double dd; int mode, ndigits, *decpt, *sign; char **rve; +(dd, mode, ndigits, decpt, sign, rve) +double dd; int mode, ndigits, *decpt, *sign; char **rve; #else - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) +(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif { - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; #ifndef Sudden_Underflow - int denorm; - ULong x; + int denorm; + ULong x; #endif - Bigint *b, *b1, *delta, *mlo, *mhi, *S; - U d2, eps, u; - double ds; - char *s, *s0; + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U d2, eps, u; + double ds; + char *s, *s0; #ifndef No_leftright #ifdef IEEE_Arith - U eps1; + U eps1; #endif #endif #ifdef SET_INEXACT - int inexact, oldinexact; + int inexact, oldinexact; #endif #ifdef Honor_FLT_ROUNDS /*{*/ - int Rounding; + int Rounding; #ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */ - Rounding = Flt_Rounds; + Rounding = Flt_Rounds; #else /*}{*/ - Rounding = 1; - switch(fegetround()) { - case FE_TOWARDZERO: Rounding = 0; break; - case FE_UPWARD: Rounding = 2; break; - case FE_DOWNWARD: Rounding = 3; - } + Rounding = 1; + switch(fegetround()) { + case FE_TOWARDZERO: Rounding = 0; break; + case FE_UPWARD: Rounding = 2; break; + case FE_DOWNWARD: Rounding = 3; + } #endif /*}}*/ #endif /*}*/ #ifndef MULTIPLE_THREADS - if (dtoa_result) { - freedtoa(dtoa_result); - dtoa_result = 0; - } -#endif - - u.d = dd; - if (word0(&u) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(&u) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } +#endif + + u.d = dd; + if (word0(&u) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(&u) &= ~Sign_bit; /* clear sign bit */ + } + else { + *sign = 0; + } #if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith - if ((word0(&u) & Exp_mask) == Exp_mask) + if ((word0(&u) & Exp_mask) == Exp_mask) #else - if (word0(&u) == 0x8000) + if (word0(&u) == 0x8000) #endif - { - /* Infinity or NaN */ - *decpt = 9999; + { + /* Infinity or NaN */ + *decpt = 9999; #ifdef IEEE_Arith - if (!word1(&u) && !(word0(&u) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); + if (!word1(&u) && !(word0(&u) & 0xfffff)) { + return nrv_alloc("Infinity", rve, 8); + } #endif - return nrv_alloc("NaN", rve, 3); - } + return nrv_alloc("NaN", rve, 3); + } #endif #ifdef IBM - dval(&u) += 0; /* normalize */ + dval(&u) += 0; /* normalize */ #endif - if (!dval(&u)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } + if (!dval(&u)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } #ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; + try_quick = oldinexact = get_inexact(); + inexact = 1; #endif #ifdef Honor_FLT_ROUNDS - if (Rounding >= 2) { - if (*sign) - Rounding = Rounding == 2 ? 0 : 2; - else - if (Rounding != 2) - Rounding = 0; - } + if (Rounding >= 2) { + if (*sign) { + Rounding = Rounding == 2 ? 0 : 2; + } + else if (Rounding != 2) { + Rounding = 0; + } + } #endif - b = d2b(&u, &be, &bbits); + b = d2b(&u, &be, &bbits); #ifdef Sudden_Underflow - i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else - if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { + if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask>>Exp_shift1)))) { #endif - dval(&d2) = dval(&u); - word0(&d2) &= Frac_mask1; - word0(&d2) |= Exp_11; + dval(&d2) = dval(&u); + word0(&d2) &= Frac_mask1; + word0(&d2) |= Exp_11; #ifdef IBM - if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) - dval(&d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; + if (j = 11 - hi0bits(word0(&d2) & Frac_mask)) { + dval(&d2) /= 1 << j; + } +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; #ifdef IBM - i <<= 2; - i += j; + i <<= 2; + i += j; #endif #ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) - : word1(&u) << (32 - i); - dval(&d2) = x; - word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(&u) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; + denorm = 0; +} +else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(&u) << (64 - i) | word1(&u) >> (i - 32) + : word1(&u) << (32 - i); + dval(&d2) = x; + word0(&d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; +} +#endif +ds = (dval(&d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; +k = (int)ds; +if (ds < 0. && ds != k) { + k--; /* want k = floor(ds) */ +} +k_check = 1; +if (k >= 0 && k <= Ten_pmax) { + if (dval(&u) < tens[k]) { + k--; + } + k_check = 0; +} +j = bbits - i - 1; +if (j >= 0) { + b2 = 0; + s2 = j; +} +else { + b2 = -j; + s2 = 0; +} +if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; +} +else { + b2 -= k; + b5 = -k; + s5 = 0; +} +if (mode < 0 || mode > 9) { + mode = 0; +} #ifndef SET_INEXACT #ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; +try_quick = Rounding == 1; #else - try_quick = 1; +try_quick = 1; #endif #endif /*SET_INEXACT*/ - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ - /* silence erroneous "gcc -Wall" warning. */ - switch(mode) { - case 0: - case 1: - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i); +if (mode > 5) { + mode -= 4; + try_quick = 0; +} +leftright = 1; +ilim = ilim1 = -1; /* Values for cases 0 and 1; done here to */ +/* silence erroneous "gcc -Wall" warning. */ +switch(mode) { +case 0: +case 1: + i = 18; + ndigits = 0; + break; +case 2: + leftright = 0; +/* no break */ +case 4: + if (ndigits <= 0) { + ndigits = 1; + } + ilim = ilim1 = i = ndigits; + break; +case 3: + leftright = 0; +/* no break */ +case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) { + i = 1; + } +} +s = s0 = rv_alloc(i); #ifdef Honor_FLT_ROUNDS - if (mode > 1 && Rounding != 1) - leftright = 0; -#endif - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(&d2) = dval(&u); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(&u) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(&u) /= ds; - } - else if ((j1 = -k)) { - dval(&u) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(&u) *= bigtens[i]; - } - } - if (k_check && dval(&u) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(&u) *= 10.; - ieps++; - } - dval(&eps) = ieps*dval(&u) + 7.; - word0(&eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(&u) -= 5.; - if (dval(&u) > dval(&eps)) - goto one_digit; - if (dval(&u) < -dval(&eps)) - goto no_digits; - goto fast_failed; - } +if (mode > 1 && Rounding != 1) { + leftright = 0; +} +#endif + +if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(&d2) = dval(&u); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(&u) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(&u) /= ds; + } + else if ((j1 = -k)) { + dval(&u) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(&u) *= bigtens[i]; + } + } + if (k_check && dval(&u) < 1. && ilim > 0) { + if (ilim1 <= 0) { + goto fast_failed; + } + ilim = ilim1; + k--; + dval(&u) *= 10.; + ieps++; + } + dval(&eps) = ieps*dval(&u) + 7.; + word0(&eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(&u) -= 5.; + if (dval(&u) > dval(&eps)) { + goto one_digit; + } + if (dval(&u) < -dval(&eps)) { + goto no_digits; + } + goto fast_failed; + } #ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(&eps) = 0.5/tens[ilim-1] - dval(&eps); #ifdef IEEE_Arith - if (k0 < 0 && j1 >= 307) { - eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */ - word0(&eps1) -= Exp_msk1 * (Bias+P-1); - dval(&eps1) *= tens[j1 & 0xf]; - for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++) - if (j & 1) - dval(&eps1) *= bigtens[i]; - if (eps.d < eps1.d) - eps.d = eps1.d; - } -#endif - for(i = 0;;) { - L = dval(&u); - dval(&u) -= L; - *s++ = '0' + (int)L; - if (1. - dval(&u) < dval(&eps)) - goto bump_up; - if (dval(&u) < dval(&eps)) - goto ret1; - if (++i >= ilim) - break; - dval(&eps) *= 10.; - dval(&u) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - dval(&eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u)); - if (!(dval(&u) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(&u) > 0.5 + dval(&eps)) - goto bump_up; - else if (dval(&u) < 0.5 - dval(&eps)) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } + if (k0 < 0 && j1 >= 307) { + eps1.d = 1.01e256; /* 1.01 allows roundoff in the next few lines */ + word0(&eps1) -= Exp_msk1 * (Bias+P-1); + dval(&eps1) *= tens[j1 & 0xf]; + for(i = 0, j = (j1-256) >> 4; j; j >>= 1, i++) + if (j & 1) { + dval(&eps1) *= bigtens[i]; + } + if (eps.d < eps1.d) { + eps.d = eps1.d; + } + } +#endif + for(i = 0;;) { + L = dval(&u); + dval(&u) -= L; + *s++ = '0' + (int)L; + if (1. - dval(&u) < dval(&eps)) { + goto bump_up; + } + if (dval(&u) < dval(&eps)) { + goto ret1; + } + if (++i >= ilim) { + break; + } + dval(&eps) *= 10.; + dval(&u) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(&eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u)); + if (!(dval(&u) -= L)) { + ilim = i; + } + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(&u) > 0.5 + dval(&eps)) { + goto bump_up; + } + else if (dval(&u) < 0.5 - dval(&eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } #ifndef No_leftright - } -#endif - fast_failed: - s = s0; - dval(&u) = dval(&d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(&u) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1;; i++, dval(&u) *= 10.) { - L = (Long)(dval(&u) / ds); - dval(&u) -= L*ds; + } +#endif +fast_failed: + s = s0; + dval(&u) = dval(&d2); + k = k0; + ilim = ilim0; +} + +/* Do we have a "small" integer? */ + +if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(&u) <= 5*ds) { + goto no_digits; + } + goto one_digit; + } + for(i = 1;; i++, dval(&u) *= 10.) { + L = (Long)(dval(&u) / ds); + dval(&u) -= L*ds; #ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(&u) < 0) { - L--; - dval(&u) += ds; - } -#endif - *s++ = '0' + (int)L; - if (!dval(&u)) { + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(&u) < 0) { + L--; + dval(&u) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(&u)) { #ifdef SET_INEXACT - inexact = 0; + inexact = 0; #endif - break; - } - if (i == ilim) { + break; + } + if (i == ilim) { #ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } + if (mode > 1) + switch(Rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } #endif - dval(&u) += dval(&u); + dval(&u) += dval(&u); #ifdef ROUND_BIASED - if (dval(&u) >= ds) + if (dval(&u) >= ds) #else - if (dval(&u) > ds || (dval(&u) == ds && L & 1)) -#endif - { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - i = + if (dval(&u) > ds || (dval(&u) == ds && L & 1)) +#endif + { +bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; +} + +m2 = b2; +m5 = b5; +mhi = mlo = 0; +if (leftright) { + i = #ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : + denorm ? be + (Bias + (P-1) - 1 + 1) : #endif #ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); #else - 1 + P - bbits; -#endif - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if ((j = b5 - m5)) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); +} +if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; +} +if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if ((j = b5 - m5)) { + b = pow5mult(b, j); + } + } + else { + b = pow5mult(b, b5); + } +} +S = i2b(1); +if (s5 > 0) { + S = pow5mult(S, s5); +} + +/* Check for special case that d is a normalized power of 2. */ + +spec_case = 0; +if ((mode < 2 || leftright) #ifdef Honor_FLT_ROUNDS - && Rounding == 1 + && Rounding == 1 #endif - ) { - if (!word1(&u) && !(word0(&u) & Bndry_mask) + ) { + if (!word1(&u) && !(word0(&u) & Bndry_mask) #ifndef Sudden_Underflow - && word0(&u) & (Exp_mask & ~Exp_msk1) -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ - i = dshift(S, s2); - b2 += i; - m2 += i; - s2 += i; - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); + && word0(&u) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } +} + +/* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ +i = dshift(S, s2); +b2 += i; +m2 += i; +s2 += i; +if (b2 > 0) { + b = lshift(b, b2); +} +if (s2 > 0) { + S = lshift(S, s2); +} +if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) { + mhi = multadd(mhi, 10, 0); + } + ilim = ilim1; + } +} +if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ +no_digits: + k = -1 - ndigits; + goto ret; + } +one_digit: + *s++ = '1'; + k++; + goto ret; +} +if (leftright) { + if (m2 > 0) { + mhi = lshift(mhi, m2); + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;; i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); #ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(&u) & 1) + if (j1 == 0 && mode != 1 && !(word1(&u) & 1) #ifdef Honor_FLT_ROUNDS - && Rounding >= 1 -#endif - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; + && Rounding >= 1 +#endif + ) { + if (dig == '9') { + goto round_9_up; + } + if (j > 0) { + dig++; + } #ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; + else if (!b->x[0] && b->wds <= 1) { + inexact = 0; + } #endif - *s++ = dig; - goto ret; - } + *s++ = dig; + goto ret; + } #endif - if (j < 0 || (j == 0 && mode != 1 + if (j < 0 || (j == 0 && mode != 1 #ifndef ROUND_BIASED - && !(word1(&u) & 1) + && !(word1(&u) & 1) #endif - )) { - if (!b->x[0] && b->wds <= 1) { + )) { + if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT - inexact = 0; + inexact = 0; #endif - goto accept_dig; - } + goto accept_dig; + } #ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(Rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } + if (mode > 1) + switch(Rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } #endif /*Honor_FLT_ROUNDS*/ - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); #ifdef ROUND_BIASED - if (j1 >= 0 /*)*/ + if (j1 >= 0 /*)*/ #else - if ((j1 > 0 || (j1 == 0 && dig & 1)) -#endif - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { + if ((j1 > 0 || (j1 == 0 && dig & 1)) +#endif + && dig++ == '9') + goto round_9_up; + } +accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { #ifdef Honor_FLT_ROUNDS - if (!Rounding) - goto accept_dig; -#endif - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } + if (!Rounding) { + goto accept_dig; + } +#endif + if (dig == '9') { /* possible if i == 1 */ +round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } #ifdef Honor_FLT_ROUNDS - keep_dig: -#endif - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { +keep_dig: +#endif + *s++ = dig; + if (i == ilim) { + break; + } + b = multadd(b, 10, 0); + if (mlo == mhi) { + mlo = mhi = multadd(mhi, 10, 0); + } + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } +} +else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT - inexact = 0; + inexact = 0; #endif - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } + goto ret; + } + if (i >= ilim) { + break; + } + b = multadd(b, 10, 0); + } - /* Round off last digit */ +/* Round off last digit */ #ifdef Honor_FLT_ROUNDS - switch(Rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } +switch(Rounding) { +case 0: goto trimzeros; +case 2: goto roundoff; +} #endif - b = lshift(b, 1); - j = cmp(b, S); +b = lshift(b, 1); +j = cmp(b, S); #ifdef ROUND_BIASED - if (j >= 0) +if (j >= 0) #else - if (j > 0 || (j == 0 && dig & 1)) -#endif - { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { +if (j > 0 || (j == 0 && dig & 1)) +#endif +{ +roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; +} +else { #ifdef Honor_FLT_ROUNDS - trimzeros: -#endif - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: +trimzeros: +#endif + while(*--s == '0'); + s++; +} +ret: +Bfree(S); +if (mhi) { + if (mlo && mlo != mhi) { + Bfree(mlo); + } + Bfree(mhi); +} +ret1: #ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(&u) = Exp_1 + (70 << Exp_shift); - word1(&u) = 0; - dval(&u) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } +if (inexact) { + if (!oldinexact) { + word0(&u) = Exp_1 + (70 << Exp_shift); + word1(&u) = 0; + dval(&u) += 1.; + } +} +else if (!oldinexact) { + clear_inexact(); +} +#endif +Bfree(b); +*s = 0; +*decpt = k + 1; +if (rve) { + *rve = s; +} +return s0; +} #ifdef __cplusplus } #endif diff --git a/nsprpub/pr/src/misc/pralarm.c b/nsprpub/pr/src/misc/pralarm.c index 8f642bb16..8130215c2 100644 --- a/nsprpub/pr/src/misc/pralarm.c +++ b/nsprpub/pr/src/misc/pralarm.c @@ -38,21 +38,21 @@ struct PRAlarm { /* typedef'd in pralarm.h */ static PRAlarmID *pr_getNextAlarm(PRAlarm *alarm, PRAlarmID *id) { -/* - * Puts 'id' back into the sorted list iff it's not NULL. - * Removes the first element from the list and returns it (or NULL). - * List is "assumed" to be short. - * - * NB: Caller is providing locking - */ + /* + * Puts 'id' back into the sorted list iff it's not NULL. + * Removes the first element from the list and returns it (or NULL). + * List is "assumed" to be short. + * + * NB: Caller is providing locking + */ PRCList *timer; PRAlarmID *result = id; PRIntervalTime now = PR_IntervalNow(); if (!PR_CLIST_IS_EMPTY(&alarm->timers)) - { + { if (id != NULL) /* have to put this id back in */ - { + { PRIntervalTime idDelta = now - id->nextNotify; timer = alarm->timers.next; do @@ -107,12 +107,15 @@ static void PR_CALLBACK pr_alarmNotifier(void *arg) while (why == scan) { alarm->current = NULL; /* reset current id */ - if (alarm->state == alarm_inactive) why = abort; /* we're toast */ + if (alarm->state == alarm_inactive) { + why = abort; /* we're toast */ + } else if (why == scan) /* the dominant case */ { id = pr_getNextAlarm(alarm, id); /* even if it's the same */ - if (id == NULL) /* there are no alarms set */ + if (id == NULL) { /* there are no alarms set */ (void)PR_WaitCondVar(alarm->cond, PR_INTERVAL_NO_TIMEOUT); + } else { pause = id->nextNotify - (PR_IntervalNow() - id->epoch); @@ -121,8 +124,9 @@ static void PR_CALLBACK pr_alarmNotifier(void *arg) why = notify; /* set up to do our thing */ alarm->current = id; /* id we're about to schedule */ } - else - (void)PR_WaitCondVar(alarm->cond, pause); /* dally */ + else { + (void)PR_WaitCondVar(alarm->cond, pause); /* dally */ + } } } } @@ -152,21 +156,31 @@ PR_IMPLEMENT(PRAlarm*) PR_CreateAlarm(void) PRAlarm *alarm = PR_NEWZAP(PRAlarm); if (alarm != NULL) { - if ((alarm->lock = PR_NewLock()) == NULL) goto done; - if ((alarm->cond = PR_NewCondVar(alarm->lock)) == NULL) goto done; + if ((alarm->lock = PR_NewLock()) == NULL) { + goto done; + } + if ((alarm->cond = PR_NewCondVar(alarm->lock)) == NULL) { + goto done; + } alarm->state = alarm_active; PR_INIT_CLIST(&alarm->timers); alarm->notifier = PR_CreateThread( - PR_USER_THREAD, pr_alarmNotifier, alarm, - PR_GetThreadPriority(PR_GetCurrentThread()), - PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); - if (alarm->notifier == NULL) goto done; + PR_USER_THREAD, pr_alarmNotifier, alarm, + PR_GetThreadPriority(PR_GetCurrentThread()), + PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0); + if (alarm->notifier == NULL) { + goto done; + } } return alarm; done: - if (alarm->cond != NULL) PR_DestroyCondVar(alarm->cond); - if (alarm->lock != NULL) PR_DestroyLock(alarm->lock); + if (alarm->cond != NULL) { + PR_DestroyCondVar(alarm->cond); + } + if (alarm->lock != NULL) { + PR_DestroyLock(alarm->lock); + } PR_DELETE(alarm); return NULL; } /* CreateAlarm */ @@ -180,8 +194,9 @@ PR_IMPLEMENT(PRStatus) PR_DestroyAlarm(PRAlarm *alarm) rv = PR_NotifyCondVar(alarm->cond); PR_Unlock(alarm->lock); - if (rv == PR_SUCCESS) + if (rv == PR_SUCCESS) { rv = PR_JoinThread(alarm->notifier); + } if (rv == PR_SUCCESS) { PR_DestroyCondVar(alarm->cond); @@ -204,8 +219,9 @@ PR_IMPLEMENT(PRAlarmID*) PR_SetAlarm( PRAlarmID *id = PR_NEWZAP(PRAlarmID); - if (!id) + if (!id) { return NULL; + } id->alarm = alarm; PR_INIT_CLIST(&id->list); @@ -232,8 +248,9 @@ PR_IMPLEMENT(PRStatus) PR_ResetAlarm( * need locking because it can only be called from within the * notify routine. */ - if (id != id->alarm->current) + if (id != id->alarm->current) { return PR_FAILURE; + } id->period = period; id->rate = rate; id->accumulator = 1; diff --git a/nsprpub/pr/src/misc/pratom.c b/nsprpub/pr/src/misc/pratom.c index 65e6f3cd8..4f0e3da30 100644 --- a/nsprpub/pr/src/misc/pratom.c +++ b/nsprpub/pr/src/misc/pratom.c @@ -43,91 +43,94 @@ /* * lock counts should be a power of 2 */ -#define DEFAULT_ATOMIC_LOCKS 16 /* should be in sync with the number of initializers - below */ -#define MAX_ATOMIC_LOCKS (4 * 1024) +#define DEFAULT_ATOMIC_LOCKS 16 /* should be in sync with the number of initializers + below */ +#define MAX_ATOMIC_LOCKS (4 * 1024) static pthread_mutex_t static_atomic_locks[DEFAULT_ATOMIC_LOCKS] = { - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, - PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER }; + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, + PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER +}; #ifdef DEBUG static PRInt32 static_hash_lock_counts[DEFAULT_ATOMIC_LOCKS]; static PRInt32 *hash_lock_counts = static_hash_lock_counts; #endif -static PRUint32 num_atomic_locks = DEFAULT_ATOMIC_LOCKS; +static PRUint32 num_atomic_locks = DEFAULT_ATOMIC_LOCKS; static pthread_mutex_t *atomic_locks = static_atomic_locks; static PRUint32 atomic_hash_mask = DEFAULT_ATOMIC_LOCKS - 1; -#define _PR_HASH_FOR_LOCK(ptr) \ - ((PRUint32) (((PRUptrdiff) (ptr) >> 2) ^ \ - ((PRUptrdiff) (ptr) >> 8)) & \ - atomic_hash_mask) +#define _PR_HASH_FOR_LOCK(ptr) \ + ((PRUint32) (((PRUptrdiff) (ptr) >> 2) ^ \ + ((PRUptrdiff) (ptr) >> 8)) & \ + atomic_hash_mask) void _PR_MD_INIT_ATOMIC() { -char *eval; -int index; - - - PR_ASSERT(PR_FloorLog2(MAX_ATOMIC_LOCKS) == - PR_CeilingLog2(MAX_ATOMIC_LOCKS)); - - PR_ASSERT(PR_FloorLog2(DEFAULT_ATOMIC_LOCKS) == - PR_CeilingLog2(DEFAULT_ATOMIC_LOCKS)); - - if (((eval = getenv("NSPR_ATOMIC_HASH_LOCKS")) != NULL) && - ((num_atomic_locks = atoi(eval)) != DEFAULT_ATOMIC_LOCKS)) { - - if (num_atomic_locks > MAX_ATOMIC_LOCKS) - num_atomic_locks = MAX_ATOMIC_LOCKS; - else if (num_atomic_locks < 1) - num_atomic_locks = 1; - else { - num_atomic_locks = PR_FloorLog2(num_atomic_locks); - num_atomic_locks = 1L << num_atomic_locks; - } - atomic_locks = (pthread_mutex_t *) PR_Malloc(sizeof(pthread_mutex_t) * - num_atomic_locks); - if (atomic_locks) { - for (index = 0; index < num_atomic_locks; index++) { - if (pthread_mutex_init(&atomic_locks[index], NULL)) { - PR_DELETE(atomic_locks); - atomic_locks = NULL; - break; - } - } - } + char *eval; + int index; + + + PR_ASSERT(PR_FloorLog2(MAX_ATOMIC_LOCKS) == + PR_CeilingLog2(MAX_ATOMIC_LOCKS)); + + PR_ASSERT(PR_FloorLog2(DEFAULT_ATOMIC_LOCKS) == + PR_CeilingLog2(DEFAULT_ATOMIC_LOCKS)); + + if (((eval = getenv("NSPR_ATOMIC_HASH_LOCKS")) != NULL) && + ((num_atomic_locks = atoi(eval)) != DEFAULT_ATOMIC_LOCKS)) { + + if (num_atomic_locks > MAX_ATOMIC_LOCKS) { + num_atomic_locks = MAX_ATOMIC_LOCKS; + } + else if (num_atomic_locks < 1) { + num_atomic_locks = 1; + } + else { + num_atomic_locks = PR_FloorLog2(num_atomic_locks); + num_atomic_locks = 1L << num_atomic_locks; + } + atomic_locks = (pthread_mutex_t *) PR_Malloc(sizeof(pthread_mutex_t) * + num_atomic_locks); + if (atomic_locks) { + for (index = 0; index < num_atomic_locks; index++) { + if (pthread_mutex_init(&atomic_locks[index], NULL)) { + PR_DELETE(atomic_locks); + atomic_locks = NULL; + break; + } + } + } #ifdef DEBUG - if (atomic_locks) { - hash_lock_counts = PR_CALLOC(num_atomic_locks * sizeof(PRInt32)); - if (hash_lock_counts == NULL) { - PR_DELETE(atomic_locks); - atomic_locks = NULL; - } - } + if (atomic_locks) { + hash_lock_counts = PR_CALLOC(num_atomic_locks * sizeof(PRInt32)); + if (hash_lock_counts == NULL) { + PR_DELETE(atomic_locks); + atomic_locks = NULL; + } + } #endif - if (atomic_locks == NULL) { - /* - * Use statically allocated locks - */ - atomic_locks = static_atomic_locks; - num_atomic_locks = DEFAULT_ATOMIC_LOCKS; - #ifdef DEBUG - hash_lock_counts = static_hash_lock_counts; - #endif - } - atomic_hash_mask = num_atomic_locks - 1; - } - PR_ASSERT(PR_FloorLog2(num_atomic_locks) == - PR_CeilingLog2(num_atomic_locks)); + if (atomic_locks == NULL) { + /* + * Use statically allocated locks + */ + atomic_locks = static_atomic_locks; + num_atomic_locks = DEFAULT_ATOMIC_LOCKS; +#ifdef DEBUG + hash_lock_counts = static_hash_lock_counts; +#endif + } + atomic_hash_mask = num_atomic_locks - 1; + } + PR_ASSERT(PR_FloorLog2(num_atomic_locks) == + PR_CeilingLog2(num_atomic_locks)); } PRInt32 @@ -299,55 +302,57 @@ PR_AtomicAdd(PRInt32 *ptr, PRInt32 val) PR_IMPLEMENT(PRStack *) PR_CreateStack(const char *stack_name) { -PRStack *stack; + PRStack *stack; if (!_pr_initialized) { _PR_ImplicitInitialization(); } if ((stack = PR_NEW(PRStack)) == NULL) { - return NULL; - } - if (stack_name) { - stack->prstk_name = (char *) PR_Malloc(strlen(stack_name) + 1); - if (stack->prstk_name == NULL) { - PR_DELETE(stack); - return NULL; - } - strcpy(stack->prstk_name, stack_name); - } else - stack->prstk_name = NULL; + return NULL; + } + if (stack_name) { + stack->prstk_name = (char *) PR_Malloc(strlen(stack_name) + 1); + if (stack->prstk_name == NULL) { + PR_DELETE(stack); + return NULL; + } + strcpy(stack->prstk_name, stack_name); + } else { + stack->prstk_name = NULL; + } #ifndef _PR_HAVE_ATOMIC_CAS stack->prstk_lock = PR_NewLock(); - if (stack->prstk_lock == NULL) { - PR_Free(stack->prstk_name); - PR_DELETE(stack); - return NULL; - } + if (stack->prstk_lock == NULL) { + PR_Free(stack->prstk_name); + PR_DELETE(stack); + return NULL; + } #endif /* !_PR_HAVE_ATOMIC_CAS */ - stack->prstk_head.prstk_elem_next = NULL; - + stack->prstk_head.prstk_elem_next = NULL; + return stack; } PR_IMPLEMENT(PRStatus) PR_DestroyStack(PRStack *stack) { - if (stack->prstk_head.prstk_elem_next != NULL) { - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return PR_FAILURE; - } + if (stack->prstk_head.prstk_elem_next != NULL) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return PR_FAILURE; + } - if (stack->prstk_name) - PR_Free(stack->prstk_name); + if (stack->prstk_name) { + PR_Free(stack->prstk_name); + } #ifndef _PR_HAVE_ATOMIC_CAS - PR_DestroyLock(stack->prstk_lock); + PR_DestroyLock(stack->prstk_lock); #endif /* !_PR_HAVE_ATOMIC_CAS */ - PR_DELETE(stack); + PR_DELETE(stack); - return PR_SUCCESS; + return PR_SUCCESS; } #ifndef _PR_HAVE_ATOMIC_CAS @@ -356,8 +361,8 @@ PR_IMPLEMENT(void) PR_StackPush(PRStack *stack, PRStackElem *stack_elem) { PR_Lock(stack->prstk_lock); - stack_elem->prstk_elem_next = stack->prstk_head.prstk_elem_next; - stack->prstk_head.prstk_elem_next = stack_elem; + stack_elem->prstk_elem_next = stack->prstk_head.prstk_elem_next; + stack->prstk_head.prstk_elem_next = stack_elem; PR_Unlock(stack->prstk_lock); return; } @@ -365,14 +370,14 @@ PR_StackPush(PRStack *stack, PRStackElem *stack_elem) PR_IMPLEMENT(PRStackElem *) PR_StackPop(PRStack *stack) { -PRStackElem *element; + PRStackElem *element; PR_Lock(stack->prstk_lock); - element = stack->prstk_head.prstk_elem_next; - if (element != NULL) { - stack->prstk_head.prstk_elem_next = element->prstk_elem_next; - element->prstk_elem_next = NULL; /* debugging aid */ - } + element = stack->prstk_head.prstk_elem_next; + if (element != NULL) { + stack->prstk_head.prstk_elem_next = element->prstk_elem_next; + element->prstk_elem_next = NULL; /* debugging aid */ + } PR_Unlock(stack->prstk_lock); return element; } diff --git a/nsprpub/pr/src/misc/praton.c b/nsprpub/pr/src/misc/praton.c index 80c0628cc..3e729f587 100644 --- a/nsprpub/pr/src/misc/praton.c +++ b/nsprpub/pr/src/misc/praton.c @@ -10,7 +10,7 @@ /* * Copyright (c) 1983, 1990, 1993 * The Regents of the University of California. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -22,7 +22,7 @@ * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE @@ -38,14 +38,14 @@ /* * Portions Copyright (c) 1993 by Digital Equipment Corporation. - * + * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. - * + * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT @@ -78,7 +78,7 @@ static const unsigned char index_hex[256] = { XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, @@ -93,9 +93,15 @@ static const unsigned char index_hex[256] = { XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, }; -static PRBool _isdigit(char c) { return c >= '0' && c <= '9'; } -static PRBool _isxdigit(char c) { return index_hex[(unsigned char) c] != XX; } -static PRBool _isspace(char c) { return c == ' ' || (c >= '\t' && c <= '\r'); } +static PRBool _isdigit(char c) { + return c >= '0' && c <= '9'; +} +static PRBool _isxdigit(char c) { + return index_hex[(unsigned char) c] != XX; +} +static PRBool _isspace(char c) { + return c == ' ' || (c >= '\t' && c <= '\r'); +} #undef XX int @@ -115,13 +121,15 @@ pr_inet_aton(const char *cp, PRUint32 *addr) * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ - if (!_isdigit(c)) + if (!_isdigit(c)) { return (0); + } val = 0; base = 10; digit = 0; if (c == '0') { c = *++cp; - if (c == 'x' || c == 'X') + if (c == 'x' || c == 'X') { base = 16, c = *++cp; + } else { base = 8; digit = 1; @@ -129,8 +137,9 @@ pr_inet_aton(const char *cp, PRUint32 *addr) } for (;;) { if (_isdigit(c)) { - if (base == 8 && (c == '8' || c == '9')) + if (base == 8 && (c == '8' || c == '9')) { return (0); + } val = (val * base) + (c - '0'); c = *++cp; digit = 1; @@ -138,8 +147,9 @@ pr_inet_aton(const char *cp, PRUint32 *addr) val = (val << 4) + index_hex[(unsigned char) c]; c = *++cp; digit = 1; - } else + } else { break; + } } if (c == '.') { /* @@ -148,51 +158,58 @@ pr_inet_aton(const char *cp, PRUint32 *addr) * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ - if (pp >= parts + 3 || val > 0xffU) + if (pp >= parts + 3 || val > 0xffU) { return (0); + } *pp++ = val; c = *++cp; - } else + } else { break; + } } /* * Check for trailing characters. */ - if (c != '\0' && !_isspace(c)) + if (c != '\0' && !_isspace(c)) { return (0); + } /* * Did we get a valid digit? */ - if (!digit) + if (!digit) { return (0); + } /* * Concoct the address according to * the number of parts specified. */ n = pp - parts + 1; switch (n) { - case 1: /*%< a -- 32 bits */ - break; + case 1: /*%< a -- 32 bits */ + break; - case 2: /*%< a.b -- 8.24 bits */ - if (val > 0xffffffU) - return (0); - val |= (unsigned int)parts[0] << 24; - break; + case 2: /*%< a.b -- 8.24 bits */ + if (val > 0xffffffU) { + return (0); + } + val |= (unsigned int)parts[0] << 24; + break; - case 3: /*%< a.b.c -- 8.8.16 bits */ - if (val > 0xffffU) - return (0); - val |= ((unsigned int)parts[0] << 24) | ((unsigned int)parts[1] << 16); - break; + case 3: /*%< a.b.c -- 8.8.16 bits */ + if (val > 0xffffU) { + return (0); + } + val |= ((unsigned int)parts[0] << 24) | ((unsigned int)parts[1] << 16); + break; - case 4: /*%< a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xffU) - return (0); - val |= ((unsigned int)parts[0] << 24) | - ((unsigned int)parts[1] << 16) | - ((unsigned int)parts[2] << 8); - break; + case 4: /*%< a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xffU) { + return (0); + } + val |= ((unsigned int)parts[0] << 24) | + ((unsigned int)parts[1] << 16) | + ((unsigned int)parts[2] << 8); + break; } *addr = PR_htonl(val); return (1); diff --git a/nsprpub/pr/src/misc/prcountr.c b/nsprpub/pr/src/misc/prcountr.c index 0f126ad08..29d7d4ccb 100644 --- a/nsprpub/pr/src/misc/prcountr.c +++ b/nsprpub/pr/src/misc/prcountr.c @@ -10,16 +10,16 @@ ** ** Design Notes: ** -** The Counter Facility (CF) has a single anchor: qNameList. +** The Counter Facility (CF) has a single anchor: qNameList. ** The anchor is a PRCList. qNameList is a list of links in QName ** structures. From qNameList any QName structure and its -** associated RName structure can be located. -** +** associated RName structure can be located. +** ** For each QName, a list of RName structures is anchored at ** rnLink in the QName structure. -** +** ** The counter itself is embedded in the RName structure. -** +** ** For manipulating the counter database, single lock is used to ** protect the entire list: counterLock. ** @@ -29,7 +29,7 @@ ** "overloaded" for traversing the QName structures; only the ** function PR_FindNextQnameHandle() uses this overloading. ** -** +** ** ToDo (lth): decide on how to lock or atomically update ** individual counters. Candidates are: the global lock; a lock ** per RName structure; Atomic operations (Note that there are @@ -64,9 +64,9 @@ typedef struct RName PRCList link; QName *qName; PRLock *lock; - volatile PRUint32 counter; - char name[PRCOUNTER_NAME_MAX+1]; - char desc[PRCOUNTER_DESC_MAX+1]; + volatile PRUint32 counter; + char name[PRCOUNTER_NAME_MAX+1]; + char desc[PRCOUNTER_DESC_MAX+1]; } RName; @@ -87,7 +87,7 @@ static void _PR_CounterInitialize( void ) ** This function should be called only once */ PR_ASSERT( counterLock == NULL ); - + counterLock = PR_NewLock(); PR_INIT_CLIST( &qNameList ); lm = PR_NewLogModule("counters"); @@ -111,20 +111,21 @@ static void _PR_CounterInitialize( void ) ** Unlock ** */ -PR_IMPLEMENT(PRCounterHandle) - PR_CreateCounter( - const char *qName, - const char *rName, - const char *description -) +PR_IMPLEMENT(PRCounterHandle) +PR_CreateCounter( + const char *qName, + const char *rName, + const char *description +) { QName *qnp; RName *rnp; PRBool matchQname = PR_FALSE; /* Self initialize, if necessary */ - if ( counterLock == NULL ) + if ( counterLock == NULL ) { _PR_CounterInitialize(); + } /* Validate input arguments */ PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX ); @@ -157,10 +158,10 @@ PR_IMPLEMENT(PRCounterHandle) { qnp = PR_NEWZAP( QName ); PR_ASSERT( qnp != NULL ); - PR_INIT_CLIST( &qnp->link ); - PR_INIT_CLIST( &qnp->rNameList ); + PR_INIT_CLIST( &qnp->link ); + PR_INIT_CLIST( &qnp->rNameList ); strcpy( qnp->name, qName ); - PR_APPEND_LINK( &qnp->link, &qNameList ); + PR_APPEND_LINK( &qnp->link, &qNameList ); } /* Do we already have a matching RName? */ @@ -189,31 +190,31 @@ PR_IMPLEMENT(PRCounterHandle) PR_ASSERT(0); } - PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ + PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ rnp->qName = qnp; /* point the RName to the QName */ /* Unlock the Facility */ PR_Unlock( counterLock ); PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t", - qName, qnp, rName, rnp )); + qName, qnp, rName, rnp )); return((PRCounterHandle)rnp); } /* end PR_CreateCounter() */ - + /* ** */ -PR_IMPLEMENT(void) - PR_DestroyCounter( - PRCounterHandle handle +PR_IMPLEMENT(void) +PR_DestroyCounter( + PRCounterHandle handle ) { RName *rnp = (RName *)handle; QName *qnp = rnp->qName; - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", - qnp->name, rnp->name)); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", + qnp->name, rnp->name)); /* Lock the Facility */ PR_Lock( counterLock ); @@ -222,8 +223,8 @@ PR_IMPLEMENT(void) ** Remove RName from the list of RNames in QName ** and free RName */ - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", - rnp->name, rnp)); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", + rnp->name, rnp)); PR_REMOVE_LINK( &rnp->link ); PR_Free( rnp->lock ); PR_DELETE( rnp ); @@ -234,11 +235,11 @@ PR_IMPLEMENT(void) */ if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) ) { - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", - qnp->name, qnp)); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", + qnp->name, qnp)); PR_REMOVE_LINK( &qnp->link ); PR_DELETE( qnp ); - } + } /* Unlock the Facility */ PR_Unlock( counterLock ); @@ -248,10 +249,10 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(PRCounterHandle) - PR_GetCounterHandleFromName( - const char *qName, - const char *rName +PR_IMPLEMENT(PRCounterHandle) +PR_GetCounterHandleFromName( + const char *qName, + const char *rName ) { const char *qn, *rn, *desc; @@ -259,7 +260,7 @@ PR_IMPLEMENT(PRCounterHandle) RName *rnp = NULL; PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t" - "QName: %s, RName: %s", qName, rName )); + "QName: %s, RName: %s", qName, rName )); qh = PR_FindNextCounterQname( NULL ); while (qh != NULL) @@ -269,7 +270,7 @@ PR_IMPLEMENT(PRCounterHandle) { PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc ); if ( (strcmp( qName, qn ) == 0) - && (strcmp( rName, rn ) == 0 )) + && (strcmp( rName, rn ) == 0 )) { rnp = (RName *)rh; goto foundIt; @@ -287,12 +288,12 @@ foundIt: /* ** */ -PR_IMPLEMENT(void) - PR_GetCounterNameFromHandle( - PRCounterHandle handle, - const char **qName, - const char **rName, - const char **description +PR_IMPLEMENT(void) +PR_GetCounterNameFromHandle( + PRCounterHandle handle, + const char **qName, + const char **rName, + const char **description ) { RName *rnp = (RName *)handle; @@ -303,8 +304,8 @@ PR_IMPLEMENT(void) *description = rnp->desc; PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterNameFromHandle: " - "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", - qnp, rnp, qnp->name, rnp->name, rnp->desc )); + "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", + qnp, rnp, qnp->name, rnp->name, rnp->desc )); return; } /* end PR_GetCounterNameFromHandle() */ @@ -313,17 +314,17 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(void) - PR_IncrementCounter( - PRCounterHandle handle +PR_IMPLEMENT(void) +PR_IncrementCounter( + PRCounterHandle handle ) { PR_Lock(((RName *)handle)->lock); ((RName *)handle)->counter++; PR_Unlock(((RName *)handle)->lock); - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", - handle, ((RName *)handle)->counter )); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", + handle, ((RName *)handle)->counter )); return; } /* end PR_IncrementCounter() */ @@ -333,17 +334,17 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(void) - PR_DecrementCounter( - PRCounterHandle handle +PR_IMPLEMENT(void) +PR_DecrementCounter( + PRCounterHandle handle ) { PR_Lock(((RName *)handle)->lock); ((RName *)handle)->counter--; PR_Unlock(((RName *)handle)->lock); - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", - handle, ((RName *)handle)->counter )); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", + handle, ((RName *)handle)->counter )); return; } /* end PR_DecrementCounter() */ @@ -352,18 +353,18 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(void) - PR_AddToCounter( - PRCounterHandle handle, - PRUint32 value +PR_IMPLEMENT(void) +PR_AddToCounter( + PRCounterHandle handle, + PRUint32 value ) { PR_Lock(((RName *)handle)->lock); ((RName *)handle)->counter += value; PR_Unlock(((RName *)handle)->lock); - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", - handle, ((RName *)handle)->counter )); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", + handle, ((RName *)handle)->counter )); return; } /* end PR_AddToCounter() */ @@ -372,18 +373,18 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(void) - PR_SubtractFromCounter( - PRCounterHandle handle, - PRUint32 value +PR_IMPLEMENT(void) +PR_SubtractFromCounter( + PRCounterHandle handle, + PRUint32 value ) { PR_Lock(((RName *)handle)->lock); ((RName *)handle)->counter -= value; PR_Unlock(((RName *)handle)->lock); - - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", - handle, ((RName *)handle)->counter )); + + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", + handle, ((RName *)handle)->counter )); return; } /* end PR_SubtractFromCounter() */ @@ -391,13 +392,13 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(PRUint32) - PR_GetCounter( - PRCounterHandle handle +PR_IMPLEMENT(PRUint32) +PR_GetCounter( + PRCounterHandle handle ) { - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", - handle, ((RName *)handle)->counter )); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", + handle, ((RName *)handle)->counter )); return(((RName *)handle)->counter); } /* end PR_GetCounter() */ @@ -405,16 +406,16 @@ PR_IMPLEMENT(PRUint32) /* ** */ -PR_IMPLEMENT(void) - PR_SetCounter( - PRCounterHandle handle, - PRUint32 value +PR_IMPLEMENT(void) +PR_SetCounter( + PRCounterHandle handle, + PRUint32 value ) { ((RName *)handle)->counter = value; - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", - handle, ((RName *)handle)->counter )); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", + handle, ((RName *)handle)->counter )); return; } /* end PR_SetCounter() */ @@ -422,24 +423,28 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(PRCounterHandle) - PR_FindNextCounterQname( - PRCounterHandle handle +PR_IMPLEMENT(PRCounterHandle) +PR_FindNextCounterQname( + PRCounterHandle handle ) { QName *qnp = (QName *)handle; - if ( PR_CLIST_IS_EMPTY( &qNameList )) - qnp = NULL; - else if ( qnp == NULL ) + if ( PR_CLIST_IS_EMPTY( &qNameList )) { + qnp = NULL; + } + else if ( qnp == NULL ) { qnp = (QName *)PR_LIST_HEAD( &qNameList ); - else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) + } + else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) { qnp = NULL; - else + } + else { qnp = (QName *)PR_NEXT_LINK( &qnp->link ); + } - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", - handle, qnp )); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", + handle, qnp )); return((PRCounterHandle)qnp); } /* end PR_FindNextCounterQname() */ @@ -448,27 +453,31 @@ PR_IMPLEMENT(PRCounterHandle) /* ** */ -PR_IMPLEMENT(PRCounterHandle) - PR_FindNextCounterRname( - PRCounterHandle rhandle, - PRCounterHandle qhandle +PR_IMPLEMENT(PRCounterHandle) +PR_FindNextCounterRname( + PRCounterHandle rhandle, + PRCounterHandle qhandle ) { RName *rnp = (RName *)rhandle; QName *qnp = (QName *)qhandle; - if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) + if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) { rnp = NULL; - else if ( rnp == NULL ) + } + else if ( rnp == NULL ) { rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList ); - else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) + } + else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) { rnp = NULL; - else + } + else { rnp = (RName *)PR_NEXT_LINK( &rnp->link ); + } - PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", - rhandle, qhandle, rnp )); + PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", + rhandle, qhandle, rnp )); return((PRCounterHandle)rnp); } /* end PR_FindNextCounterRname() */ diff --git a/nsprpub/pr/src/misc/prdtoa.c b/nsprpub/pr/src/misc/prdtoa.c index 227692613..f0963370f 100644 --- a/nsprpub/pr/src/misc/prdtoa.c +++ b/nsprpub/pr/src/misc/prdtoa.c @@ -17,8 +17,8 @@ #include "prbit.h" #define MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) PR_Lock(dtoa_lock[n]) -#define FREE_DTOA_LOCK(n) PR_Unlock(dtoa_lock[n]) +#define ACQUIRE_DTOA_LOCK(n) PR_Lock(dtoa_lock[n]) +#define FREE_DTOA_LOCK(n) PR_Unlock(dtoa_lock[n]) static PRLock *dtoa_lock[2]; @@ -74,13 +74,13 @@ void _PR_CleanupDtoa(void) ***************************************************************/ /* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ + * with " at " changed at "@" and " dot " changed to "."). */ /* On a machine with IEEE extended-precision registers, it is * necessary to specify double-precision (53-bit) rounding precision * before invoking strtod or dtoa. If the machine uses (the equivalent * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); + * _control87(PC_53, MCW_PC); * does this with many compilers. Whether this or another call is * appropriate depends on the compiler; for this to work, it may be * necessary to #include "float.h" or another system-dependent header @@ -99,127 +99,127 @@ void _PR_CleanupDtoa(void) * * Modifications: * - * 1. We only require IEEE, IBM, or VAX double-precision - * arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). + * 1. We only require IEEE, IBM, or VAX double-precision + * arithmetic (not IEEE double-extended). + * 2. We get by with floating-point arithmetic in a case that + * Clinger missed -- when we're computing d * 10^n + * for a small integer d and the integer n is not too + * much larger than 22 (the maximum integer k for which + * we can represent 10^k exactly), we may be able to + * compute (d*10^k) * 10^(e-k) with just one roundoff. + * 3. Rather than a bit-at-a-time adjustment of the binary + * result in the hard case, we use floating-point + * arithmetic to determine the adjustment to within + * one bit; only in really hard cases do we need to + * compute a second residual. + * 4. Because of 3., we don't need a large table of powers of 10 + * for ten-to-e (just some small tables, e.g. of 10^k + * for 0 <= k <= 22). */ /* * #define IEEE_8087 for IEEE-arithmetic machines where the least - * significant byte has the lowest address. + * significant byte has the lowest address. * #define IEEE_MC68k for IEEE-arithmetic machines where the most - * significant byte has the lowest address. + * significant byte has the lowest address. * #define IEEE_ARM for IEEE-arithmetic machines where the two words - * in a double are stored in big endian order but the two shorts - * in a word are still stored in little endian order. + * in a double are stored in big endian order but the two shorts + * in a word are still stored in little endian order. * #define Long int on machines with 32-bit ints and 64-bit longs. * #define IBM for IBM mainframe-style floating-point arithmetic. * #define VAX for VAX-style floating-point arithmetic (D_floating). * #define No_leftright to omit left-right logic in fast floating-point - * computation of dtoa. + * computation of dtoa. * #define Honor_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and strtod and dtoa should round accordingly. + * and strtod and dtoa should round accordingly. * #define Check_FLT_ROUNDS if FLT_ROUNDS can assume the values 2 or 3 - * and Honor_FLT_ROUNDS is not #defined. + * and Honor_FLT_ROUNDS is not #defined. * #define RND_PRODQUOT to use rnd_prod and rnd_quot (assembly routines - * that use extended-precision instructions to compute rounded - * products and quotients) with IBM. + * that use extended-precision instructions to compute rounded + * products and quotients) with IBM. * #define ROUND_BIASED for IEEE-format with biased rounding. * #define Inaccurate_Divide for IEEE-format with correctly rounded - * products but inaccurate quotients, e.g., for Intel i860. + * products but inaccurate quotients, e.g., for Intel i860. * #define NO_LONG_LONG on machines that do not have a "long long" - * integer type (of >= 64 bits). On such machines, you can - * #define Just_16 to store 16 bits per 32-bit Long when doing - * high-precision integer arithmetic. Whether this speeds things - * up or slows things down depends on the machine and the number - * being converted. If long long is available and the name is - * something other than "long long", #define Llong to be the name, - * and if "unsigned Llong" does not work as an unsigned version of - * Llong, #define #ULLong to be the corresponding unsigned type. + * integer type (of >= 64 bits). On such machines, you can + * #define Just_16 to store 16 bits per 32-bit Long when doing + * high-precision integer arithmetic. Whether this speeds things + * up or slows things down depends on the machine and the number + * being converted. If long long is available and the name is + * something other than "long long", #define Llong to be the name, + * and if "unsigned Llong" does not work as an unsigned version of + * Llong, #define #ULLong to be the corresponding unsigned type. * #define KR_headers for old-style C function headers. * #define Bad_float_h if your system lacks a float.h or if it does not - * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, - * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. + * define some or all of DBL_DIG, DBL_MAX_10_EXP, DBL_MAX_EXP, + * FLT_RADIX, FLT_ROUNDS, and DBL_MAX. * #define MALLOC your_malloc, where your_malloc(n) acts like malloc(n) - * if memory is available and otherwise does something you deem - * appropriate. If MALLOC is undefined, malloc will be invoked - * directly -- and assumed always to succeed. Similarly, if you - * want something other than the system's free() to be called to - * recycle memory acquired from MALLOC, #define FREE to be the - * name of the alternate routine. (FREE or free is only called in - * pathological cases, e.g., in a dtoa call after a dtoa return in - * mode 3 with thousands of digits requested.) + * if memory is available and otherwise does something you deem + * appropriate. If MALLOC is undefined, malloc will be invoked + * directly -- and assumed always to succeed. Similarly, if you + * want something other than the system's free() to be called to + * recycle memory acquired from MALLOC, #define FREE to be the + * name of the alternate routine. (FREE or free is only called in + * pathological cases, e.g., in a dtoa call after a dtoa return in + * mode 3 with thousands of digits requested.) * #define Omit_Private_Memory to omit logic (added Jan. 1998) for making - * memory allocations from a private pool of memory when possible. - * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, - * unless #defined to be a different length. This default length - * suffices to get rid of MALLOC calls except for unusual cases, - * such as decimal-to-binary conversion of a very long string of - * digits. The longest string dtoa can return is about 751 bytes - * long. For conversions by strtod of strings of 800 digits and - * all dtoa conversions in single-threaded executions with 8-byte - * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte - * pointers, PRIVATE_MEM >= 7112 appears adequate. + * memory allocations from a private pool of memory when possible. + * When used, the private pool is PRIVATE_MEM bytes long: 2304 bytes, + * unless #defined to be a different length. This default length + * suffices to get rid of MALLOC calls except for unusual cases, + * such as decimal-to-binary conversion of a very long string of + * digits. The longest string dtoa can return is about 751 bytes + * long. For conversions by strtod of strings of 800 digits and + * all dtoa conversions in single-threaded executions with 8-byte + * pointers, PRIVATE_MEM >= 7400 appears to suffice; with 4-byte + * pointers, PRIVATE_MEM >= 7112 appears adequate. * #define INFNAN_CHECK on IEEE systems to cause strtod to check for - * Infinity and NaN (case insensitively). On some systems (e.g., - * some HP systems), it may be necessary to #define NAN_WORD0 - * appropriately -- to the most significant word of a quiet NaN. - * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) - * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, - * strtod also accepts (case insensitively) strings of the form - * NaN(x), where x is a string of hexadecimal digits and spaces; - * if there is only one string of hexadecimal digits, it is taken - * for the 52 fraction bits of the resulting NaN; if there are two - * or more strings of hex digits, the first is for the high 20 bits, - * the second and subsequent for the low 32 bits, with intervening - * white space ignored; but if this results in none of the 52 - * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 - * and NAN_WORD1 are used instead. + * Infinity and NaN (case insensitively). On some systems (e.g., + * some HP systems), it may be necessary to #define NAN_WORD0 + * appropriately -- to the most significant word of a quiet NaN. + * (On HP Series 700/800 machines, -DNAN_WORD0=0x7ff40000 works.) + * When INFNAN_CHECK is #defined and No_Hex_NaN is not #defined, + * strtod also accepts (case insensitively) strings of the form + * NaN(x), where x is a string of hexadecimal digits and spaces; + * if there is only one string of hexadecimal digits, it is taken + * for the 52 fraction bits of the resulting NaN; if there are two + * or more strings of hex digits, the first is for the high 20 bits, + * the second and subsequent for the low 32 bits, with intervening + * white space ignored; but if this results in none of the 52 + * fraction bits being on (an IEEE Infinity symbol), then NAN_WORD0 + * and NAN_WORD1 are used instead. * #define MULTIPLE_THREADS if the system offers preemptively scheduled - * multiple threads. In this case, you must provide (or suitably - * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed - * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed - * in pow5mult, ensures lazy evaluation of only one copy of high - * powers of 5; omitting this lock would introduce a small - * probability of wasting memory, but would otherwise be harmless.) - * You must also invoke freedtoa(s) to free the value s returned by - * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. + * multiple threads. In this case, you must provide (or suitably + * #define) two locks, acquired by ACQUIRE_DTOA_LOCK(n) and freed + * by FREE_DTOA_LOCK(n) for n = 0 or 1. (The second lock, accessed + * in pow5mult, ensures lazy evaluation of only one copy of high + * powers of 5; omitting this lock would introduce a small + * probability of wasting memory, but would otherwise be harmless.) + * You must also invoke freedtoa(s) to free the value s returned by + * dtoa. You may do so whether or not MULTIPLE_THREADS is #defined. * #define NO_IEEE_Scale to disable new (Feb. 1997) logic in strtod that - * avoids underflows on inputs whose result does not underflow. - * If you #define NO_IEEE_Scale on a machine that uses IEEE-format - * floating-point numbers and flushes underflows to zero rather - * than implementing gradual underflow, then you must also #define - * Sudden_Underflow. + * avoids underflows on inputs whose result does not underflow. + * If you #define NO_IEEE_Scale on a machine that uses IEEE-format + * floating-point numbers and flushes underflows to zero rather + * than implementing gradual underflow, then you must also #define + * Sudden_Underflow. * #define USE_LOCALE to use the current locale's decimal_point value. * #define SET_INEXACT if IEEE arithmetic is being used and extra - * computation should be done to set the inexact flag when the - * result is inexact and avoid setting inexact when the result - * is exact. In this case, dtoa.c must be compiled in - * an environment, perhaps provided by #include "dtoa.c" in a - * suitable wrapper, that defines two functions, - * int get_inexact(void); - * void clear_inexact(void); - * such that get_inexact() returns a nonzero value if the - * inexact bit is already set, and clear_inexact() sets the - * inexact bit to 0. When SET_INEXACT is #defined, strtod - * also does extra computations to set the underflow and overflow - * flags when appropriate (i.e., when the result is tiny and - * inexact or when it is a numeric value rounded to +-infinity). + * computation should be done to set the inexact flag when the + * result is inexact and avoid setting inexact when the result + * is exact. In this case, dtoa.c must be compiled in + * an environment, perhaps provided by #include "dtoa.c" in a + * suitable wrapper, that defines two functions, + * int get_inexact(void); + * void clear_inexact(void); + * such that get_inexact() returns a nonzero value if the + * inexact bit is already set, and clear_inexact() sets the + * inexact bit to 0. When SET_INEXACT is #defined, strtod + * also does extra computations to set the underflow and overflow + * flags when appropriate (i.e., when the result is tiny and + * inexact or when it is a numeric value rounded to +-infinity). * #define NO_ERRNO if strtod should not assign errno = ERANGE when - * the result overflows to +-Infinity or underflows to 0. + * the result overflows to +-Infinity or underflows to 0. */ #ifndef Long @@ -337,7 +337,10 @@ extern "C" { Exactly one of IEEE_8087, IEEE_MC68k, IEEE_ARM, VAX, or IBM should be defined. #endif -typedef union { double d; ULong L[2]; } U; +typedef union { + double d; + ULong L[2]; +} U; #define dval(x) (x).d #ifdef IEEE_8087 @@ -393,7 +396,7 @@ typedef union { double d; ULong L[2]; } U; #define Int_max 14 #ifndef NO_IEEE_Scale #define Avoid_Underflow -#ifdef Flush_Denorm /* debugging option */ +#ifdef Flush_Denorm /* debugging option */ #undef Sudden_Underflow #endif #endif @@ -432,7 +435,7 @@ typedef union { double d; ULong L[2]; } U; #define Bias 65 #define Exp_1 0x41000000 #define Exp_11 0x41000000 -#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ +#define Ebits 8 /* exponent has 7 bits, but 8 is the right value in b2d */ #define Frac_mask 0xffffff #define Frac_mask1 0xffffff #define Bletch 4 @@ -515,7 +518,7 @@ extern double rnd_prod(double, double), rnd_quot(double, double); * slower. Hence the default is now to store 32 bits per Long. */ #endif -#else /* long long available */ +#else /* long long available */ #ifndef Llong #define Llong long long #endif @@ -525,969 +528,1006 @@ extern double rnd_prod(double, double), rnd_quot(double, double); #endif /* NO_LONG_LONG */ #ifndef MULTIPLE_THREADS -#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ -#define FREE_DTOA_LOCK(n) /*nothing*/ +#define ACQUIRE_DTOA_LOCK(n) /*nothing*/ +#define FREE_DTOA_LOCK(n) /*nothing*/ #endif #define Kmax 7 - struct -Bigint { - struct Bigint *next; - int k, maxwds, sign, wds; - ULong x[1]; - }; +struct + Bigint { + struct Bigint *next; + int k, maxwds, sign, wds; + ULong x[1]; +}; - typedef struct Bigint Bigint; +typedef struct Bigint Bigint; - static Bigint *freelist[Kmax+1]; +static Bigint *freelist[Kmax+1]; - static Bigint * +static Bigint * Balloc #ifdef KR_headers - (k) int k; +(k) int k; #else - (int k) +(int k) #endif { - int x; - Bigint *rv; + int x; + Bigint *rv; #ifndef Omit_Private_Memory - unsigned int len; + unsigned int len; #endif - ACQUIRE_DTOA_LOCK(0); - /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ - /* but this case seems very unlikely. */ - if (k <= Kmax && (rv = freelist[k])) - freelist[k] = rv->next; - else { - x = 1 << k; + ACQUIRE_DTOA_LOCK(0); + /* The k > Kmax case does not need ACQUIRE_DTOA_LOCK(0), */ + /* but this case seems very unlikely. */ + if (k <= Kmax && (rv = freelist[k])) { + freelist[k] = rv->next; + } + else { + x = 1 << k; #ifdef Omit_Private_Memory - rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); -#else - len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) - /sizeof(double); - if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { - rv = (Bigint*)pmem_next; - pmem_next += len; - } - else - rv = (Bigint*)MALLOC(len*sizeof(double)); -#endif - rv->k = k; - rv->maxwds = x; - } - FREE_DTOA_LOCK(0); - rv->sign = rv->wds = 0; - return rv; - } - - static void + rv = (Bigint *)MALLOC(sizeof(Bigint) + (x-1)*sizeof(ULong)); +#else + len = (sizeof(Bigint) + (x-1)*sizeof(ULong) + sizeof(double) - 1) + /sizeof(double); + if (k <= Kmax && pmem_next - private_mem + len <= PRIVATE_mem) { + rv = (Bigint*)pmem_next; + pmem_next += len; + } + else { + rv = (Bigint*)MALLOC(len*sizeof(double)); + } +#endif + rv->k = k; + rv->maxwds = x; + } + FREE_DTOA_LOCK(0); + rv->sign = rv->wds = 0; + return rv; +} + +static void Bfree #ifdef KR_headers - (v) Bigint *v; +(v) Bigint *v; #else - (Bigint *v) +(Bigint *v) #endif { - if (v) { - if (v->k > Kmax) + if (v) { + if (v->k > Kmax) #ifdef FREE - FREE((void*)v); + FREE((void*)v); #else - free((void*)v); + free((void*)v); #endif - else { - ACQUIRE_DTOA_LOCK(0); - v->next = freelist[v->k]; - freelist[v->k] = v; - FREE_DTOA_LOCK(0); - } - } - } + else { + ACQUIRE_DTOA_LOCK(0); + v->next = freelist[v->k]; + freelist[v->k] = v; + FREE_DTOA_LOCK(0); + } + } +} #define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \ y->wds*sizeof(Long) + 2*sizeof(int)) - static Bigint * +static Bigint * multadd #ifdef KR_headers - (b, m, a) Bigint *b; int m, a; +(b, m, a) Bigint *b; int m, a; #else - (Bigint *b, int m, int a) /* multiply by m and add a */ +(Bigint *b, int m, int a) /* multiply by m and add a */ #endif { - int i, wds; + int i, wds; #ifdef ULLong - ULong *x; - ULLong carry, y; + ULong *x; + ULLong carry, y; #else - ULong carry, *x, y; + ULong carry, *x, y; #ifdef Pack_32 - ULong xi, z; + ULong xi, z; #endif #endif - Bigint *b1; + Bigint *b1; - wds = b->wds; - x = b->x; - i = 0; - carry = a; - do { + wds = b->wds; + x = b->x; + i = 0; + carry = a; + do { #ifdef ULLong - y = *x * (ULLong)m + carry; - carry = y >> 32; - *x++ = y & FFFFFFFF; + y = *x * (ULLong)m + carry; + carry = y >> 32; + *x++ = y & FFFFFFFF; #else #ifdef Pack_32 - xi = *x; - y = (xi & 0xffff) * m + carry; - z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#else - y = *x * m + carry; - carry = y >> 16; - *x++ = y & 0xffff; -#endif -#endif - } - while(++i < wds); - if (carry) { - if (wds >= b->maxwds) { - b1 = Balloc(b->k+1); - Bcopy(b1, b); - Bfree(b); - b = b1; - } - b->x[wds++] = carry; - b->wds = wds; - } - return b; - } - - static Bigint * + xi = *x; + y = (xi & 0xffff) * m + carry; + z = (xi >> 16) * m + (y >> 16); + carry = z >> 16; + *x++ = (z << 16) + (y & 0xffff); +#else + y = *x * m + carry; + carry = y >> 16; + *x++ = y & 0xffff; +#endif +#endif + } + while(++i < wds); + if (carry) { + if (wds >= b->maxwds) { + b1 = Balloc(b->k+1); + Bcopy(b1, b); + Bfree(b); + b = b1; + } + b->x[wds++] = carry; + b->wds = wds; + } + return b; +} + +static Bigint * s2b #ifdef KR_headers - (s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; +(s, nd0, nd, y9) CONST char *s; int nd0, nd; ULong y9; #else - (CONST char *s, int nd0, int nd, ULong y9) +(CONST char *s, int nd0, int nd, ULong y9) #endif { - Bigint *b; - int i, k; - Long x, y; + Bigint *b; + int i, k; + Long x, y; - x = (nd + 8) / 9; - for(k = 0, y = 1; x > y; y <<= 1, k++) ; + x = (nd + 8) / 9; + for(k = 0, y = 1; x > y; y <<= 1, k++) ; #ifdef Pack_32 - b = Balloc(k); - b->x[0] = y9; - b->wds = 1; -#else - b = Balloc(k+1); - b->x[0] = y9 & 0xffff; - b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; -#endif - - i = 9; - if (9 < nd0) { - s += 9; - do b = multadd(b, 10, *s++ - '0'); - while(++i < nd0); - s++; - } - else - s += 10; - for(; i < nd; i++) - b = multadd(b, 10, *s++ - '0'); - return b; - } - - static int + b = Balloc(k); + b->x[0] = y9; + b->wds = 1; +#else + b = Balloc(k+1); + b->x[0] = y9 & 0xffff; + b->wds = (b->x[1] = y9 >> 16) ? 2 : 1; +#endif + + i = 9; + if (9 < nd0) { + s += 9; + do { + b = multadd(b, 10, *s++ - '0'); + } + while(++i < nd0); + s++; + } + else { + s += 10; + } + for(; i < nd; i++) { + b = multadd(b, 10, *s++ - '0'); + } + return b; +} + +static int hi0bits #ifdef KR_headers - (x) register ULong x; +(x) register ULong x; #else - (register ULong x) +(register ULong x) #endif { #ifdef PR_HAVE_BUILTIN_BITSCAN32 - return( (!x) ? 32 : pr_bitscan_clz32(x) ); -#else - register int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; + return( (!x) ? 32 : pr_bitscan_clz32(x) ); +#else + register int k = 0; + + if (!(x & 0xffff0000)) { + k = 16; + x <<= 16; + } + if (!(x & 0xff000000)) { + k += 8; + x <<= 8; + } + if (!(x & 0xf0000000)) { + k += 4; + x <<= 4; + } + if (!(x & 0xc0000000)) { + k += 2; + x <<= 2; + } + if (!(x & 0x80000000)) { + k++; + if (!(x & 0x40000000)) { + return 32; + } + } + return k; #endif /* PR_HAVE_BUILTIN_BITSCAN32 */ - } +} - static int +static int lo0bits #ifdef KR_headers - (y) ULong *y; +(y) ULong *y; #else - (ULong *y) +(ULong *y) #endif { #ifdef PR_HAVE_BUILTIN_BITSCAN32 - int k; - ULong x = *y; - - if (x>1) - *y = ( x >> (k = pr_bitscan_ctz32(x)) ); - else - k = ((x ^ 1) << 5); -#else - register int k; - register ULong x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; + int k; + ULong x = *y; + + if (x>1) { + *y = ( x >> (k = pr_bitscan_ctz32(x)) ); + } + else { + k = ((x ^ 1) << 5); + } +#else + register int k; + register ULong x = *y; + + if (x & 7) { + if (x & 1) { + return 0; + } + if (x & 2) { + *y = x >> 1; + return 1; + } + *y = x >> 2; + return 2; + } + k = 0; + if (!(x & 0xffff)) { + k = 16; + x >>= 16; + } + if (!(x & 0xff)) { + k += 8; + x >>= 8; + } + if (!(x & 0xf)) { + k += 4; + x >>= 4; + } + if (!(x & 0x3)) { + k += 2; + x >>= 2; + } + if (!(x & 1)) { + k++; + x >>= 1; + if (!x) { + return 32; + } + } + *y = x; #endif /* PR_HAVE_BUILTIN_BITSCAN32 */ - return k; - } + return k; +} - static Bigint * +static Bigint * i2b #ifdef KR_headers - (i) int i; +(i) int i; #else - (int i) +(int i) #endif { - Bigint *b; + Bigint *b; - b = Balloc(1); - b->x[0] = i; - b->wds = 1; - return b; - } + b = Balloc(1); + b->x[0] = i; + b->wds = 1; + return b; +} - static Bigint * +static Bigint * mult #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - Bigint *c; - int k, wa, wb, wc; - ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; - ULong y; + Bigint *c; + int k, wa, wb, wc; + ULong *x, *xa, *xae, *xb, *xbe, *xc, *xc0; + ULong y; #ifdef ULLong - ULLong carry, z; + ULLong carry, z; #else - ULong carry, z; + ULong carry, z; #ifdef Pack_32 - ULong z2; -#endif -#endif - - if (a->wds < b->wds) { - c = a; - a = b; - b = c; - } - k = a->k; - wa = a->wds; - wb = b->wds; - wc = wa + wb; - if (wc > a->maxwds) - k++; - c = Balloc(k); - for(x = c->x, xa = x + wc; x < xa; x++) - *x = 0; - xa = a->x; - xae = xa + wa; - xb = b->x; - xbe = xb + wb; - xc0 = c->x; + ULong z2; +#endif +#endif + + if (a->wds < b->wds) { + c = a; + a = b; + b = c; + } + k = a->k; + wa = a->wds; + wb = b->wds; + wc = wa + wb; + if (wc > a->maxwds) { + k++; + } + c = Balloc(k); + for(x = c->x, xa = x + wc; x < xa; x++) { + *x = 0; + } + xa = a->x; + xae = xa + wa; + xb = b->x; + xbe = xb + wb; + xc0 = c->x; #ifdef ULLong - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (ULLong)y + *xc + carry; - carry = z >> 32; - *xc++ = z & FFFFFFFF; - } - while(x < xae); - *xc = carry; - } - } + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * (ULLong)y + *xc + carry; + carry = z >> 32; + *xc++ = z & FFFFFFFF; + } + while(x < xae); + *xc = carry; + } + } #else #ifdef Pack_32 - for(; xb < xbe; xb++, xc0++) { - if (y = *xb & 0xffff) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - Storeinc(xc, z2, z); - } - while(x < xae); - *xc = carry; - } - if (y = *xb >> 16) { - x = xa; - xc = xc0; - carry = 0; - z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - Storeinc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } - while(x < xae); - *xc = z2; - } - } -#else - for(; xb < xbe; xc0++) { - if (y = *xb++) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * y + *xc + carry; - carry = z >> 16; - *xc++ = z & 0xffff; - } - while(x < xae); - *xc = carry; - } - } -#endif -#endif - for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; - c->wds = wc; - return c; - } - - static Bigint *p5s; - - static Bigint * + for(; xb < xbe; xb++, xc0++) { + if (y = *xb & 0xffff) { + x = xa; + xc = xc0; + carry = 0; + do { + z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; + carry = z >> 16; + z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; + carry = z2 >> 16; + Storeinc(xc, z2, z); + } + while(x < xae); + *xc = carry; + } + if (y = *xb >> 16) { + x = xa; + xc = xc0; + carry = 0; + z2 = *xc; + do { + z = (*x & 0xffff) * y + (*xc >> 16) + carry; + carry = z >> 16; + Storeinc(xc, z, z2); + z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; + carry = z2 >> 16; + } + while(x < xae); + *xc = z2; + } + } +#else + for(; xb < xbe; xc0++) { + if (y = *xb++) { + x = xa; + xc = xc0; + carry = 0; + do { + z = *x++ * y + *xc + carry; + carry = z >> 16; + *xc++ = z & 0xffff; + } + while(x < xae); + *xc = carry; + } + } +#endif +#endif + for(xc0 = c->x, xc = xc0 + wc; wc > 0 && !*--xc; --wc) ; + c->wds = wc; + return c; +} + +static Bigint *p5s; + +static Bigint * pow5mult #ifdef KR_headers - (b, k) Bigint *b; int k; +(b, k) Bigint *b; int k; #else - (Bigint *b, int k) +(Bigint *b, int k) #endif { - Bigint *b1, *p5, *p51; - int i; - static int p05[3] = { 5, 25, 125 }; + Bigint *b1, *p5, *p51; + int i; + static int p05[3] = { 5, 25, 125 }; - if (i = k & 3) - b = multadd(b, p05[i-1], 0); + if (i = k & 3) { + b = multadd(b, p05[i-1], 0); + } - if (!(k >>= 2)) - return b; - if (!(p5 = p5s)) { - /* first time */ + if (!(k >>= 2)) { + return b; + } + if (!(p5 = p5s)) { + /* first time */ #ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p5 = p5s)) { - p5 = p5s = i2b(625); - p5->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p5 = p5s = i2b(625); - p5->next = 0; -#endif - } - for(;;) { - if (k & 1) { - b1 = mult(b, p5); - Bfree(b); - b = b1; - } - if (!(k >>= 1)) - break; - if (!(p51 = p5->next)) { + ACQUIRE_DTOA_LOCK(1); + if (!(p5 = p5s)) { + p5 = p5s = i2b(625); + p5->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p5 = p5s = i2b(625); + p5->next = 0; +#endif + } + for(;;) { + if (k & 1) { + b1 = mult(b, p5); + Bfree(b); + b = b1; + } + if (!(k >>= 1)) { + break; + } + if (!(p51 = p5->next)) { #ifdef MULTIPLE_THREADS - ACQUIRE_DTOA_LOCK(1); - if (!(p51 = p5->next)) { - p51 = p5->next = mult(p5,p5); - p51->next = 0; - } - FREE_DTOA_LOCK(1); -#else - p51 = p5->next = mult(p5,p5); - p51->next = 0; -#endif - } - p5 = p51; - } - return b; - } - - static Bigint * + ACQUIRE_DTOA_LOCK(1); + if (!(p51 = p5->next)) { + p51 = p5->next = mult(p5,p5); + p51->next = 0; + } + FREE_DTOA_LOCK(1); +#else + p51 = p5->next = mult(p5,p5); + p51->next = 0; +#endif + } + p5 = p51; + } + return b; +} + +static Bigint * lshift #ifdef KR_headers - (b, k) Bigint *b; int k; +(b, k) Bigint *b; int k; #else - (Bigint *b, int k) +(Bigint *b, int k) #endif { - int i, k1, n, n1; - Bigint *b1; - ULong *x, *x1, *xe, z; + int i, k1, n, n1; + Bigint *b1; + ULong *x, *x1, *xe, z; #ifdef Pack_32 - n = k >> 5; -#else - n = k >> 4; -#endif - k1 = b->k; - n1 = n + b->wds + 1; - for(i = b->maxwds; n1 > i; i <<= 1) - k1++; - b1 = Balloc(k1); - x1 = b1->x; - for(i = 0; i < n; i++) - *x1++ = 0; - x = b->x; - xe = x + b->wds; + n = k >> 5; +#else + n = k >> 4; +#endif + k1 = b->k; + n1 = n + b->wds + 1; + for(i = b->maxwds; n1 > i; i <<= 1) { + k1++; + } + b1 = Balloc(k1); + x1 = b1->x; + for(i = 0; i < n; i++) { + *x1++ = 0; + } + x = b->x; + xe = x + b->wds; #ifdef Pack_32 - if (k &= 0x1f) { - k1 = 32 - k; - z = 0; - do { - *x1++ = *x << k | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#else - if (k &= 0xf) { - k1 = 16 - k; - z = 0; - do { - *x1++ = *x << k & 0xffff | z; - z = *x++ >> k1; - } - while(x < xe); - if (*x1 = z) - ++n1; - } -#endif - else do - *x1++ = *x++; - while(x < xe); - b1->wds = n1 - 1; - Bfree(b); - return b1; - } - - static int + if (k &= 0x1f) { + k1 = 32 - k; + z = 0; + do { + *x1++ = *x << k | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) { + ++n1; + } + } +#else + if (k &= 0xf) { + k1 = 16 - k; + z = 0; + do { + *x1++ = *x << k & 0xffff | z; + z = *x++ >> k1; + } + while(x < xe); + if (*x1 = z) { + ++n1; + } + } +#endif + else do { + *x1++ = *x++; + } + while(x < xe); + b1->wds = n1 - 1; + Bfree(b); + return b1; +} + +static int cmp #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - ULong *xa, *xa0, *xb, *xb0; - int i, j; + ULong *xa, *xa0, *xb, *xb0; + int i, j; - i = a->wds; - j = b->wds; + i = a->wds; + j = b->wds; #ifdef DEBUG - if (i > 1 && !a->x[i-1]) - Bug("cmp called with a->x[a->wds-1] == 0"); - if (j > 1 && !b->x[j-1]) - Bug("cmp called with b->x[b->wds-1] == 0"); -#endif - if (i -= j) - return i; - xa0 = a->x; - xa = xa0 + j; - xb0 = b->x; - xb = xb0 + j; - for(;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; - } - - static Bigint * + if (i > 1 && !a->x[i-1]) { + Bug("cmp called with a->x[a->wds-1] == 0"); + } + if (j > 1 && !b->x[j-1]) { + Bug("cmp called with b->x[b->wds-1] == 0"); + } +#endif + if (i -= j) { + return i; + } + xa0 = a->x; + xa = xa0 + j; + xb0 = b->x; + xb = xb0 + j; + for(;;) { + if (*--xa != *--xb) { + return *xa < *xb ? -1 : 1; + } + if (xa <= xa0) { + break; + } + } + return 0; +} + +static Bigint * diff #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - Bigint *c; - int i, wa, wb; - ULong *xa, *xae, *xb, *xbe, *xc; + Bigint *c; + int i, wa, wb; + ULong *xa, *xae, *xb, *xbe, *xc; #ifdef ULLong - ULLong borrow, y; + ULLong borrow, y; #else - ULong borrow, y; + ULong borrow, y; #ifdef Pack_32 - ULong z; -#endif -#endif - - i = cmp(a,b); - if (!i) { - c = Balloc(0); - c->wds = 1; - c->x[0] = 0; - return c; - } - if (i < 0) { - c = a; - a = b; - b = c; - i = 1; - } - else - i = 0; - c = Balloc(a->k); - c->sign = i; - wa = a->wds; - xa = a->x; - xae = xa + wa; - wb = b->wds; - xb = b->x; - xbe = xb + wb; - xc = c->x; - borrow = 0; + ULong z; +#endif +#endif + + i = cmp(a,b); + if (!i) { + c = Balloc(0); + c->wds = 1; + c->x[0] = 0; + return c; + } + if (i < 0) { + c = a; + a = b; + b = c; + i = 1; + } + else { + i = 0; + } + c = Balloc(a->k); + c->sign = i; + wa = a->wds; + xa = a->x; + xae = xa + wa; + wb = b->wds; + xb = b->x; + xbe = xb + wb; + xc = c->x; + borrow = 0; #ifdef ULLong - do { - y = (ULLong)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = y >> 32 & (ULong)1; - *xc++ = y & FFFFFFFF; - } + do { + y = (ULLong)*xa++ - *xb++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = y >> 32 & (ULong)1; + *xc++ = y & FFFFFFFF; + } #else #ifdef Pack_32 - do { - y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } - while(xb < xbe); - while(xa < xae) { - y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(xc, z, y); - } -#else - do { - y = *xa++ - *xb++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } - while(xb < xbe); - while(xa < xae) { - y = *xa++ - borrow; - borrow = (y & 0x10000) >> 16; - *xc++ = y & 0xffff; - } -#endif -#endif - while(!*--xc) - wa--; - c->wds = wa; - return c; - } - - static double + do { + y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } + while(xb < xbe); + while(xa < xae) { + y = (*xa & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*xa++ >> 16) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(xc, z, y); + } +#else + do { + y = *xa++ - *xb++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } + while(xb < xbe); + while(xa < xae) { + y = *xa++ - borrow; + borrow = (y & 0x10000) >> 16; + *xc++ = y & 0xffff; + } +#endif +#endif + while(!*--xc) { + wa--; + } + c->wds = wa; + return c; +} + +static double ulp #ifdef KR_headers - (dx) double dx; +(dx) double dx; #else - (double dx) +(double dx) #endif { - register Long L; - U x, a; + register Long L; + U x, a; - dval(x) = dx; - L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; + dval(x) = dx; + L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; #ifndef Avoid_Underflow #ifndef Sudden_Underflow - if (L > 0) { + if (L > 0) { #endif #endif #ifdef IBM - L |= Exp_msk1 >> 4; + L |= Exp_msk1 >> 4; #endif - word0(a) = L; - word1(a) = 0; + word0(a) = L; + word1(a) = 0; #ifndef Avoid_Underflow #ifndef Sudden_Underflow - } - else { - L = -L >> Exp_shift; - if (L < Exp_shift) { - word0(a) = 0x80000 >> L; - word1(a) = 0; - } - else { - word0(a) = 0; - L -= Exp_shift; - word1(a) = L >= 31 ? 1 : 1 << 31 - L; - } - } -#endif -#endif - return dval(a); - } - - static double + } + else { + L = -L >> Exp_shift; + if (L < Exp_shift) { + word0(a) = 0x80000 >> L; + word1(a) = 0; + } + else { + word0(a) = 0; + L -= Exp_shift; + word1(a) = L >= 31 ? 1 : 1 << 31 - L; + } + } +#endif +#endif + return dval(a); +} + +static double b2d #ifdef KR_headers - (a, e) Bigint *a; int *e; +(a, e) Bigint *a; int *e; #else - (Bigint *a, int *e) +(Bigint *a, int *e) #endif { - ULong *xa, *xa0, w, y, z; - int k; - U d; + ULong *xa, *xa0, w, y, z; + int k; + U d; #ifdef VAX - ULong d0, d1; + ULong d0, d1; #else #define d0 word0(d) #define d1 word1(d) #endif - xa0 = a->x; - xa = xa0 + a->wds; - y = *--xa; + xa0 = a->x; + xa = xa0 + a->wds; + y = *--xa; #ifdef DEBUG - if (!y) Bug("zero y in b2d"); + if (!y) { + Bug("zero y in b2d"); + } #endif - k = hi0bits(y); - *e = 32 - k; + k = hi0bits(y); + *e = 32 - k; #ifdef Pack_32 - if (k < Ebits) { - d0 = Exp_1 | y >> Ebits - k; - w = xa > xa0 ? *--xa : 0; - d1 = y << (32-Ebits) + k | w >> Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | y << k | z >> 32 - k; - y = xa > xa0 ? *--xa : 0; - d1 = z << k | y >> 32 - k; - } - else { - d0 = Exp_1 | y; - d1 = z; - } -#else - if (k < Ebits + 16) { - z = xa > xa0 ? *--xa : 0; - d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; - w = xa > xa0 ? *--xa : 0; - y = xa > xa0 ? *--xa : 0; - d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; - goto ret_d; - } - z = xa > xa0 ? *--xa : 0; - w = xa > xa0 ? *--xa : 0; - k -= Ebits + 16; - d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; - y = xa > xa0 ? *--xa : 0; - d1 = w << k + 16 | y << k; -#endif - ret_d: + if (k < Ebits) { + d0 = Exp_1 | y >> Ebits - k; + w = xa > xa0 ? *--xa : 0; + d1 = y << (32-Ebits) + k | w >> Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + if (k -= Ebits) { + d0 = Exp_1 | y << k | z >> 32 - k; + y = xa > xa0 ? *--xa : 0; + d1 = z << k | y >> 32 - k; + } + else { + d0 = Exp_1 | y; + d1 = z; + } +#else + if (k < Ebits + 16) { + z = xa > xa0 ? *--xa : 0; + d0 = Exp_1 | y << k - Ebits | z >> Ebits + 16 - k; + w = xa > xa0 ? *--xa : 0; + y = xa > xa0 ? *--xa : 0; + d1 = z << k + 16 - Ebits | w << k - Ebits | y >> 16 + Ebits - k; + goto ret_d; + } + z = xa > xa0 ? *--xa : 0; + w = xa > xa0 ? *--xa : 0; + k -= Ebits + 16; + d0 = Exp_1 | y << k + 16 | z << k | w >> 16 - k; + y = xa > xa0 ? *--xa : 0; + d1 = w << k + 16 | y << k; +#endif +ret_d: #ifdef VAX - word0(d) = d0 >> 16 | d0 << 16; - word1(d) = d1 >> 16 | d1 << 16; + word0(d) = d0 >> 16 | d0 << 16; + word1(d) = d1 >> 16 | d1 << 16; #else #undef d0 #undef d1 #endif - return dval(d); - } + return dval(d); +} - static Bigint * +static Bigint * d2b #ifdef KR_headers - (dd, e, bits) double dd; int *e, *bits; +(dd, e, bits) double dd; int *e, *bits; #else - (double dd, int *e, int *bits) +(double dd, int *e, int *bits) #endif { - U d; - Bigint *b; - int de, k; - ULong *x, y, z; + U d; + Bigint *b; + int de, k; + ULong *x, y, z; #ifndef Sudden_Underflow - int i; + int i; #endif #ifdef VAX - ULong d0, d1; + ULong d0, d1; #endif - dval(d) = dd; + dval(d) = dd; #ifdef VAX - d0 = word0(d) >> 16 | word0(d) << 16; - d1 = word1(d) >> 16 | word1(d) << 16; + d0 = word0(d) >> 16 | word0(d) << 16; + d1 = word1(d) >> 16 | word1(d) << 16; #else #define d0 word0(d) #define d1 word1(d) #endif #ifdef Pack_32 - b = Balloc(1); + b = Balloc(1); #else - b = Balloc(2); + b = Balloc(2); #endif - x = b->x; + x = b->x; - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ + z = d0 & Frac_mask; + d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ #ifdef Sudden_Underflow - de = (int)(d0 >> Exp_shift); + de = (int)(d0 >> Exp_shift); #ifndef IBM - z |= Exp_msk11; + z |= Exp_msk11; #endif #else - if (de = (int)(d0 >> Exp_shift)) - z |= Exp_msk1; + if (de = (int)(d0 >> Exp_shift)) { + z |= Exp_msk1; + } #endif #ifdef Pack_32 - if (y = d1) { - if (k = lo0bits(&y)) { - x[0] = y | z << 32 - k; - z >>= k; - } - else - x[0] = y; + if (y = d1) { + if (k = lo0bits(&y)) { + x[0] = y | z << 32 - k; + z >>= k; + } + else { + x[0] = y; + } #ifndef Sudden_Underflow - i = + i = #endif - b->wds = (x[1] = z) ? 2 : 1; - } - else { - k = lo0bits(&z); - x[0] = z; + b->wds = (x[1] = z) ? 2 : 1; + } + else { + k = lo0bits(&z); + x[0] = z; #ifndef Sudden_Underflow - i = -#endif - b->wds = 1; - k += 32; - } -#else - if (y = d1) { - if (k = lo0bits(&y)) - if (k >= 16) { - x[0] = y | z << 32 - k & 0xffff; - x[1] = z >> k - 16 & 0xffff; - x[2] = z >> k; - i = 2; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16 | z << 16 - k & 0xffff; - x[2] = z >> k & 0xffff; - x[3] = z >> k+16; - i = 3; - } - else { - x[0] = y & 0xffff; - x[1] = y >> 16; - x[2] = z & 0xffff; - x[3] = z >> 16; - i = 3; - } - } - else { + i = +#endif + b->wds = 1; + k += 32; + } +#else + if (y = d1) { + if (k = lo0bits(&y)) + if (k >= 16) { + x[0] = y | z << 32 - k & 0xffff; + x[1] = z >> k - 16 & 0xffff; + x[2] = z >> k; + i = 2; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16 | z << 16 - k & 0xffff; + x[2] = z >> k & 0xffff; + x[3] = z >> k+16; + i = 3; + } + else { + x[0] = y & 0xffff; + x[1] = y >> 16; + x[2] = z & 0xffff; + x[3] = z >> 16; + i = 3; + } + } + else { #ifdef DEBUG - if (!z) - Bug("Zero passed to d2b"); -#endif - k = lo0bits(&z); - if (k >= 16) { - x[0] = z; - i = 0; - } - else { - x[0] = z & 0xffff; - x[1] = z >> 16; - i = 1; - } - k += 32; - } - while(!x[i]) - --i; - b->wds = i + 1; + if (!z) { + Bug("Zero passed to d2b"); + } +#endif + k = lo0bits(&z); + if (k >= 16) { + x[0] = z; + i = 0; + } + else { + x[0] = z & 0xffff; + x[1] = z >> 16; + i = 1; + } + k += 32; + } + while(!x[i]) { + --i; + } + b->wds = i + 1; #endif #ifndef Sudden_Underflow - if (de) { + if (de) { #endif #ifdef IBM - *e = (de - Bias - (P-1) << 2) + k; - *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); + *e = (de - Bias - (P-1) << 2) + k; + *bits = 4*P + 8 - k - hi0bits(word0(d) & Frac_mask); #else - *e = de - Bias - (P-1) + k; - *bits = P - k; + *e = de - Bias - (P-1) + k; + *bits = P - k; #endif #ifndef Sudden_Underflow - } - else { - *e = de - Bias - (P-1) + 1 + k; + } + else { + *e = de - Bias - (P-1) + 1 + k; #ifdef Pack_32 - *bits = 32*i - hi0bits(x[i-1]); + *bits = 32*i - hi0bits(x[i-1]); #else - *bits = (i+2)*16 - hi0bits(x[i]); + *bits = (i+2)*16 - hi0bits(x[i]); #endif - } + } #endif - return b; - } + return b; +} #undef d0 #undef d1 - static double +static double ratio #ifdef KR_headers - (a, b) Bigint *a, *b; +(a, b) Bigint *a, *b; #else - (Bigint *a, Bigint *b) +(Bigint *a, Bigint *b) #endif { - U da, db; - int k, ka, kb; + U da, db; + int k, ka, kb; - dval(da) = b2d(a, &ka); - dval(db) = b2d(b, &kb); + dval(da) = b2d(a, &ka); + dval(db) = b2d(b, &kb); #ifdef Pack_32 - k = ka - kb + 32*(a->wds - b->wds); + k = ka - kb + 32*(a->wds - b->wds); #else - k = ka - kb + 16*(a->wds - b->wds); + k = ka - kb + 16*(a->wds - b->wds); #endif #ifdef IBM - if (k > 0) { - word0(da) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(da) *= 1 << k; - } - else { - k = -k; - word0(db) += (k >> 2)*Exp_msk1; - if (k &= 3) - dval(db) *= 1 << k; - } -#else - if (k > 0) - word0(da) += k*Exp_msk1; - else { - k = -k; - word0(db) += k*Exp_msk1; - } -#endif - return dval(da) / dval(db); - } - - static CONST double + if (k > 0) { + word0(da) += (k >> 2)*Exp_msk1; + if (k &= 3) { + dval(da) *= 1 << k; + } + } + else { + k = -k; + word0(db) += (k >> 2)*Exp_msk1; + if (k &= 3) { + dval(db) *= 1 << k; + } + } +#else + if (k > 0) { + word0(da) += k*Exp_msk1; + } + else { + k = -k; + word0(db) += k*Exp_msk1; + } +#endif + return dval(da) / dval(db); +} + +static CONST double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, + 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, + 1e20, 1e21, 1e22 #ifdef VAX - , 1e23, 1e24 + , 1e23, 1e24 #endif - }; +}; - static CONST double +static CONST double #ifdef IEEE_Arith bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; static CONST double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, #ifdef Avoid_Underflow - 9007199254740992.*9007199254740992.e-256 - /* = 2^106 * 1e-53 */ + 9007199254740992.*9007199254740992.e-256 + /* = 2^106 * 1e-53 */ #else - 1e-256 + 1e-256 #endif - }; + }; /* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ /* flag unnecessarily. It leads to a song and dance at the end of strtod. */ #define Scale_Bit 0x10 @@ -1518,1139 +1558,1243 @@ static CONST double tinytens[] = { 1e-16, 1e-32 }; #define NAN_WORD1 0 #endif - static int +static int match #ifdef KR_headers - (sp, t) char **sp, *t; +(sp, t) char **sp, *t; #else - (CONST char **sp, char *t) +(CONST char **sp, char *t) #endif { - int c, d; - CONST char *s = *sp; - - while(d = *t++) { - if ((c = *++s) >= 'A' && c <= 'Z') - c += 'a' - 'A'; - if (c != d) - return 0; - } - *sp = s + 1; - return 1; - } + int c, d; + CONST char *s = *sp; + + while(d = *t++) { + if ((c = *++s) >= 'A' && c <= 'Z') { + c += 'a' - 'A'; + } + if (c != d) { + return 0; + } + } + *sp = s + 1; + return 1; +} #ifndef No_Hex_NaN - static void +static void hexnan #ifdef KR_headers - (rvp, sp) double *rvp; CONST char **sp; +(rvp, sp) double *rvp; CONST char **sp; #else - (double *rvp, CONST char **sp) +(double *rvp, CONST char **sp) #endif { - ULong c, x[2]; - CONST char *s; - int havedig, udx0, xshift; - - x[0] = x[1] = 0; - havedig = xshift = 0; - udx0 = 1; - s = *sp; - while(c = *(CONST unsigned char*)++s) { - if (c >= '0' && c <= '9') - c -= '0'; - else if (c >= 'a' && c <= 'f') - c += 10 - 'a'; - else if (c >= 'A' && c <= 'F') - c += 10 - 'A'; - else if (c <= ' ') { - if (udx0 && havedig) { - udx0 = 0; - xshift = 1; - } - continue; - } - else if (/*(*/ c == ')' && havedig) { - *sp = s + 1; - break; - } - else - return; /* invalid form: don't change *sp */ - havedig = 1; - if (xshift) { - xshift = 0; - x[0] = x[1]; - x[1] = 0; - } - if (udx0) - x[0] = (x[0] << 4) | (x[1] >> 28); - x[1] = (x[1] << 4) | c; - } - if ((x[0] &= 0xfffff) || x[1]) { - word0(*rvp) = Exp_mask | x[0]; - word1(*rvp) = x[1]; - } - } + ULong c, x[2]; + CONST char *s; + int havedig, udx0, xshift; + + x[0] = x[1] = 0; + havedig = xshift = 0; + udx0 = 1; + s = *sp; + while(c = *(CONST unsigned char*)++s) { + if (c >= '0' && c <= '9') { + c -= '0'; + } + else if (c >= 'a' && c <= 'f') { + c += 10 - 'a'; + } + else if (c >= 'A' && c <= 'F') { + c += 10 - 'A'; + } + else if (c <= ' ') { + if (udx0 && havedig) { + udx0 = 0; + xshift = 1; + } + continue; + } + else if (/*(*/ c == ')' && havedig) { + *sp = s + 1; + break; + } + else { + return; /* invalid form: don't change *sp */ + } + havedig = 1; + if (xshift) { + xshift = 0; + x[0] = x[1]; + x[1] = 0; + } + if (udx0) { + x[0] = (x[0] << 4) | (x[1] >> 28); + } + x[1] = (x[1] << 4) | c; + } + if ((x[0] &= 0xfffff) || x[1]) { + word0(*rvp) = Exp_mask | x[0]; + word1(*rvp) = x[1]; + } +} #endif /*No_Hex_NaN*/ #endif /* INFNAN_CHECK */ - PR_IMPLEMENT(double) +PR_IMPLEMENT(double) PR_strtod #ifdef KR_headers - (s00, se) CONST char *s00; char **se; +(s00, se) CONST char *s00; char **se; #else - (CONST char *s00, char **se) +(CONST char *s00, char **se) #endif { #ifdef Avoid_Underflow - int scale; -#endif - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - CONST char *s, *s0, *s1; - double aadj, aadj1, adj; - U aadj2, rv, rv0; - Long L; - ULong y, z; - Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; + int scale; +#endif + int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, + e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; + CONST char *s, *s0, *s1; + double aadj, aadj1, adj; + U aadj2, rv, rv0; + Long L; + ULong y, z; + Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; #ifdef SET_INEXACT - int inexact, oldinexact; + int inexact, oldinexact; #endif #ifdef Honor_FLT_ROUNDS - int rounding; + int rounding; #endif #ifdef USE_LOCALE - CONST char *s2; -#endif - - if (!_pr_initialized) _PR_ImplicitInitialization(); - - sign = nz0 = nz = 0; - dval(rv) = 0.; - for(s = s00;;s++) switch(*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - break2: - if (*s == '0') { - nz0 = 1; - while(*++s == '0') ; - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = 10*y + c - '0'; - else if (nd < 16) - z = 10*z + c - '0'; - nd0 = nd; + CONST char *s2; +#endif + + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + + sign = nz0 = nz = 0; + dval(rv) = 0.; + for(s = s00;; s++) switch(*s) { + case '-': + sign = 1; + /* no break */ + case '+': + if (*++s) { + goto break2; + } + /* no break */ + case 0: + goto ret0; + case '\t': + case '\n': + case '\v': + case '\f': + case '\r': + case ' ': + continue; + default: + goto break2; + } +break2: + if (*s == '0') { + nz0 = 1; + while(*++s == '0') ; + if (!*s) { + goto ret; + } + } + s0 = s; + y = z = 0; + for(nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) + if (nd < 9) { + y = 10*y + c - '0'; + } + else if (nd < 16) { + z = 10*z + c - '0'; + } + nd0 = nd; #ifdef USE_LOCALE - s1 = localeconv()->decimal_point; - if (c == *s1) { - c = '.'; - if (*++s1) { - s2 = s; - for(;;) { - if (*++s2 != *s1) { - c = 0; - break; - } - if (!*++s1) { - s = s2; - break; - } - } - } - } -#endif - if (c == '.') { - c = *++s; - if (!nd) { - for(; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto have_dig; - } - goto dig_done; - } - for(; c >= '0' && c <= '9'; c = *++s) { - have_dig: - nz++; - if (c -= '0') { - nf += nz; - for(i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = 10*y + c; - else if (nd <= DBL_DIG + 1) - z = 10*z + c; - nz = 0; - } - } - } - dig_done: - if (nd > 64 * 1024) - goto ret0; - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) { - goto ret0; - } - s00 = s; - esign = 0; - switch(c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while(c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while((c = *++s) >= '0' && c <= '9') - L = 10*L + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } - else - e = 0; - } - else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { + s1 = localeconv()->decimal_point; + if (c == *s1) { + c = '.'; + if (*++s1) { + s2 = s; + for(;;) { + if (*++s2 != *s1) { + c = 0; + break; + } + if (!*++s1) { + s = s2; + break; + } + } + } + } +#endif + if (c == '.') { + c = *++s; + if (!nd) { + for(; c == '0'; c = *++s) { + nz++; + } + if (c > '0' && c <= '9') { + s0 = s; + nf += nz; + nz = 0; + goto have_dig; + } + goto dig_done; + } + for(; c >= '0' && c <= '9'; c = *++s) { +have_dig: + nz++; + if (c -= '0') { + nf += nz; + for(i = 1; i < nz; i++) + if (nd++ < 9) { + y *= 10; + } + else if (nd <= DBL_DIG + 1) { + z *= 10; + } + if (nd++ < 9) { + y = 10*y + c; + } + else if (nd <= DBL_DIG + 1) { + z = 10*z + c; + } + nz = 0; + } + } + } +dig_done: + if (nd > 64 * 1024) { + goto ret0; + } + e = 0; + if (c == 'e' || c == 'E') { + if (!nd && !nz && !nz0) { + goto ret0; + } + s00 = s; + esign = 0; + switch(c = *++s) { + case '-': + esign = 1; + case '+': + c = *++s; + } + if (c >= '0' && c <= '9') { + while(c == '0') { + c = *++s; + } + if (c > '0' && c <= '9') { + L = c - '0'; + s1 = s; + while((c = *++s) >= '0' && c <= '9') { + L = 10*L + c - '0'; + } + if (s - s1 > 8 || L > 19999) + /* Avoid confusion from exponents + * so large that e might overflow. + */ + { + e = 19999; /* safe for 16 bit ints */ + } + else { + e = (int)L; + } + if (esign) { + e = -e; + } + } + else { + e = 0; + } + } + else { + s = s00; + } + } + if (!nd) { + if (!nz && !nz0) { #ifdef INFNAN_CHECK - /* Check for Nan and Infinity */ - switch(c) { - case 'i': - case 'I': - if (match(&s,"nf")) { - --s; - if (!match(&s,"inity")) - ++s; - word0(rv) = 0x7ff00000; - word1(rv) = 0; - goto ret; - } - break; - case 'n': - case 'N': - if (match(&s, "an")) { - word0(rv) = NAN_WORD0; - word1(rv) = NAN_WORD1; + /* Check for Nan and Infinity */ + switch(c) { + case 'i': + case 'I': + if (match(&s,"nf")) { + --s; + if (!match(&s,"inity")) { + ++s; + } + word0(rv) = 0x7ff00000; + word1(rv) = 0; + goto ret; + } + break; + case 'n': + case 'N': + if (match(&s, "an")) { + word0(rv) = NAN_WORD0; + word1(rv) = NAN_WORD1; #ifndef No_Hex_NaN - if (*s == '(') /*)*/ - hexnan(&rv, &s); + if (*s == '(') { /*)*/ + hexnan(&rv, &s); + } #endif - goto ret; - } - } + goto ret; + } + } #endif /* INFNAN_CHECK */ - ret0: - s = s00; - sign = 0; - } - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(rv) = y; - if (k > 9) { +ret0: + s = s00; + sign = 0; + } + goto ret; + } + e1 = e -= nf; + + /* Now we have nd0 digits, starting at s0, followed by a + * decimal point, followed by nd-nd0 digits. The number we're + * after is the integer represented by those digits times + * 10**e */ + + if (!nd0) { + nd0 = nd; + } + k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; + dval(rv) = y; + if (k > 9) { #ifdef SET_INEXACT - if (k > DBL_DIG) - oldinexact = get_inexact(); + if (k > DBL_DIG) { + oldinexact = get_inexact(); + } #endif - dval(rv) = tens[k - 9] * dval(rv) + z; - } - bd0 = 0; - if (nd <= DBL_DIG + dval(rv) = tens[k - 9] * dval(rv) + z; + } + bd0 = 0; + if (nd <= DBL_DIG #ifndef RND_PRODQUOT #ifndef Honor_FLT_ROUNDS - && Flt_Rounds == 1 + && Flt_Rounds == 1 #endif #endif - ) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { + ) { + if (!e) { + goto ret; + } + if (e > 0) { + if (e <= Ten_pmax) { #ifdef VAX - goto vax_ovfl_check; + goto vax_ovfl_check; #else #ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - /* rv = */ rounded_product(dval(rv), tens[e]); - goto ret; -#endif - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + /* rv = */ rounded_product(dval(rv), tens[e]); + goto ret; +#endif + } + i = DBL_DIG - nd; + if (e <= Ten_pmax + i) { + /* A fancier test would sometimes let us do + * this for larger i values. + */ #ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } -#endif - e -= i; - dval(rv) *= tens[i]; + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } +#endif + e -= i; + dval(rv) *= tens[i]; #ifdef VAX - /* VAX exponent range is so narrow we must - * worry about overflow here... - */ - vax_ovfl_check: - word0(rv) -= P*Exp_msk1; - /* rv = */ rounded_product(dval(rv), tens[e]); - if ((word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) - goto ovfl; - word0(rv) += P*Exp_msk1; -#else - /* rv = */ rounded_product(dval(rv), tens[e]); -#endif - goto ret; - } - } + /* VAX exponent range is so narrow we must + * worry about overflow here... + */ +vax_ovfl_check: + word0(rv) -= P*Exp_msk1; + /* rv = */ rounded_product(dval(rv), tens[e]); + if ((word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + goto ovfl; + } + word0(rv) += P*Exp_msk1; +#else + /* rv = */ rounded_product(dval(rv), tens[e]); +#endif + goto ret; + } + } #ifndef Inaccurate_Divide - else if (e >= -Ten_pmax) { + else if (e >= -Ten_pmax) { #ifdef Honor_FLT_ROUNDS - /* round correctly FLT_ROUNDS = 2 or 3 */ - if (sign) { - rv = -rv; - sign = 0; - } + /* round correctly FLT_ROUNDS = 2 or 3 */ + if (sign) { + rv = -rv; + sign = 0; + } #endif - /* rv = */ rounded_quotient(dval(rv), tens[-e]); - goto ret; - } + /* rv = */ rounded_quotient(dval(rv), tens[-e]); + goto ret; + } #endif - } - e1 += nd - k; + } + e1 += nd - k; #ifdef IEEE_Arith #ifdef SET_INEXACT - inexact = 1; - if (k <= DBL_DIG) - oldinexact = get_inexact(); + inexact = 1; + if (k <= DBL_DIG) { + oldinexact = get_inexact(); + } #endif #ifdef Avoid_Underflow - scale = 0; + scale = 0; #endif #ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } + if ((rounding = Flt_Rounds) >= 2) { + if (sign) { + rounding = rounding == 2 ? 0 : 2; + } + else if (rounding != 2) { + rounding = 0; + } + } #endif #endif /*IEEE_Arith*/ - /* Get starting approximation = rv * 10**e1 */ + /* Get starting approximation = rv * 10**e1 */ - if (e1 > 0) { - if (i = e1 & 15) - dval(rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { - ovfl: + if (e1 > 0) { + if (i = e1 & 15) { + dval(rv) *= tens[i]; + } + if (e1 &= ~15) { + if (e1 > DBL_MAX_10_EXP) { +ovfl: #ifndef NO_ERRNO - PR_SetError(PR_RANGE_ERROR, 0); + PR_SetError(PR_RANGE_ERROR, 0); #endif - /* Can't trust HUGE_VAL */ + /* Can't trust HUGE_VAL */ #ifdef IEEE_Arith #ifdef Honor_FLT_ROUNDS - switch(rounding) { - case 0: /* toward 0 */ - case 3: /* toward -infinity */ - word0(rv) = Big0; - word1(rv) = Big1; - break; - default: - word0(rv) = Exp_mask; - word1(rv) = 0; - } + switch(rounding) { + case 0: /* toward 0 */ + case 3: /* toward -infinity */ + word0(rv) = Big0; + word1(rv) = Big1; + break; + default: + word0(rv) = Exp_mask; + word1(rv) = 0; + } #else /*Honor_FLT_ROUNDS*/ - word0(rv) = Exp_mask; - word1(rv) = 0; + word0(rv) = Exp_mask; + word1(rv) = 0; #endif /*Honor_FLT_ROUNDS*/ #ifdef SET_INEXACT - /* set overflow bit */ - dval(rv0) = 1e300; - dval(rv0) *= dval(rv0); + /* set overflow bit */ + dval(rv0) = 1e300; + dval(rv0) *= dval(rv0); #endif #else /*IEEE_Arith*/ - word0(rv) = Big0; - word1(rv) = Big1; + word0(rv) = Big0; + word1(rv) = Big1; #endif /*IEEE_Arith*/ - if (bd0) - goto retfree; - goto ret; - } - e1 >>= 4; - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(rv) -= P*Exp_msk1; - dval(rv) *= bigtens[j]; - if ((z = word0(rv) & Exp_mask) - > Exp_msk1*(DBL_MAX_EXP+Bias-P)) - goto ovfl; - if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(rv) = Big0; - word1(rv) = Big1; - } - else - word0(rv) += P*Exp_msk1; - } - } - else if (e1 < 0) { - e1 = -e1; - if (i = e1 & 15) - dval(rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; + if (bd0) { + goto retfree; + } + goto ret; + } + e1 >>= 4; + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) { + dval(rv) *= bigtens[j]; + } + /* The last multiplication could overflow. */ + word0(rv) -= P*Exp_msk1; + dval(rv) *= bigtens[j]; + if ((z = word0(rv) & Exp_mask) + > Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + goto ovfl; + } + if (z > Exp_msk1*(DBL_MAX_EXP+Bias-1-P)) { + /* set to largest number */ + /* (Can't trust DBL_MAX) */ + word0(rv) = Big0; + word1(rv) = Big1; + } + else { + word0(rv) += P*Exp_msk1; + } + } + } + else if (e1 < 0) { + e1 = -e1; + if (i = e1 & 15) { + dval(rv) /= tens[i]; + } + if (e1 >>= 4) { + if (e1 >= 1 << n_bigtens) { + goto undfl; + } #ifdef Avoid_Underflow - if (e1 & Scale_Bit) - scale = 2*P; - for(j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) - >> Exp_shift)) > 0) { - /* scaled rv is denormal; zap j low bits */ - if (j >= 32) { - word1(rv) = 0; - if (j >= 53) - word0(rv) = (P+2)*Exp_msk1; - else - word0(rv) &= 0xffffffff << j-32; - } - else - word1(rv) &= 0xffffffff << j; - } -#else - for(j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(rv) *= tinytens[j]; - /* The last multiplication could underflow. */ - dval(rv0) = dval(rv); - dval(rv) *= tinytens[j]; - if (!dval(rv)) { - dval(rv) = 2.*dval(rv0); - dval(rv) *= tinytens[j]; -#endif - if (!dval(rv)) { - undfl: - dval(rv) = 0.; + if (e1 & Scale_Bit) { + scale = 2*P; + } + for(j = 0; e1 > 0; j++, e1 >>= 1) + if (e1 & 1) { + dval(rv) *= tinytens[j]; + } + if (scale && (j = 2*P + 1 - ((word0(rv) & Exp_mask) + >> Exp_shift)) > 0) { + /* scaled rv is denormal; zap j low bits */ + if (j >= 32) { + word1(rv) = 0; + if (j >= 53) { + word0(rv) = (P+2)*Exp_msk1; + } + else { + word0(rv) &= 0xffffffff << j-32; + } + } + else { + word1(rv) &= 0xffffffff << j; + } + } +#else + for(j = 0; e1 > 1; j++, e1 >>= 1) + if (e1 & 1) { + dval(rv) *= tinytens[j]; + } + /* The last multiplication could underflow. */ + dval(rv0) = dval(rv); + dval(rv) *= tinytens[j]; + if (!dval(rv)) { + dval(rv) = 2.*dval(rv0); + dval(rv) *= tinytens[j]; +#endif + if (!dval(rv)) { +undfl: + dval(rv) = 0.; #ifndef NO_ERRNO - PR_SetError(PR_RANGE_ERROR, 0); + PR_SetError(PR_RANGE_ERROR, 0); #endif - if (bd0) - goto retfree; - goto ret; - } + if (bd0) { + goto retfree; + } + goto ret; + } #ifndef Avoid_Underflow - word0(rv) = Tiny0; - word1(rv) = Tiny1; - /* The refinement below will clean - * this approximation up. - */ - } -#endif - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - bd0 = s2b(s0, nd0, nd, y); - - for(;;) { - bd = Balloc(bd0->k); - Bcopy(bd, bd0); - bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ - bs = i2b(1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } - else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; + word0(rv) = Tiny0; + word1(rv) = Tiny1; + /* The refinement below will clean + * this approximation up. + */ + } +#endif + } +} + +/* Now the hard part -- adjusting rv to the correct value.*/ + +/* Put digits into bd: true value = bd * 10^e */ + +bd0 = s2b(s0, nd0, nd, y); + +for(;;) { + bd = Balloc(bd0->k); + Bcopy(bd, bd0); + bb = d2b(dval(rv), &bbe, &bbbits); /* rv = bb * 2^bbe */ + bs = i2b(1); + + if (e >= 0) { + bb2 = bb5 = 0; + bd2 = bd5 = e; + } + else { + bb2 = bb5 = -e; + bd2 = bd5 = 0; + } + if (bbe >= 0) { + bb2 += bbe; + } + else { + bd2 -= bbe; + } + bs2 = bb2; #ifdef Honor_FLT_ROUNDS - if (rounding != 1) - bs2++; + if (rounding != 1) { + bs2++; + } #endif #ifdef Avoid_Underflow - j = bbe - scale; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; + j = bbe - scale; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) { /* denormal */ + j += P - Emin; + } + else { + j = P + 1 - bbbits; + } #else /*Avoid_Underflow*/ #ifdef Sudden_Underflow #ifdef IBM - j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); + j = 1 + 4*P - 3 - bbbits + ((bbe + bbbits - 1) & 3); #else - j = P + 1 - bbbits; + j = P + 1 - bbbits; #endif #else /*Sudden_Underflow*/ - j = bbe; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; + j = bbe; + i = j + bbbits - 1; /* logb(rv) */ + if (i < Emin) { /* denormal */ + j += P - Emin; + } + else { + j = P + 1 - bbbits; + } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - bb2 += j; - bd2 += j; + bb2 += j; + bd2 += j; #ifdef Avoid_Underflow - bd2 += scale; -#endif - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - bs = pow5mult(bs, bb5); - bb1 = mult(bs, bb); - Bfree(bb); - bb = bb1; - } - if (bb2 > 0) - bb = lshift(bb, bb2); - if (bd5 > 0) - bd = pow5mult(bd, bd5); - if (bd2 > 0) - bd = lshift(bd, bd2); - if (bs2 > 0) - bs = lshift(bs, bs2); - delta = diff(bb, bd); - dsign = delta->sign; - delta->sign = 0; - i = cmp(delta, bs); + bd2 += scale; +#endif + i = bb2 < bd2 ? bb2 : bd2; + if (i > bs2) { + i = bs2; + } + if (i > 0) { + bb2 -= i; + bd2 -= i; + bs2 -= i; + } + if (bb5 > 0) { + bs = pow5mult(bs, bb5); + bb1 = mult(bs, bb); + Bfree(bb); + bb = bb1; + } + if (bb2 > 0) { + bb = lshift(bb, bb2); + } + if (bd5 > 0) { + bd = pow5mult(bd, bd5); + } + if (bd2 > 0) { + bd = lshift(bd, bd2); + } + if (bs2 > 0) { + bs = lshift(bs, bs2); + } + delta = diff(bb, bd); + dsign = delta->sign; + delta->sign = 0; + i = cmp(delta, bs); #ifdef Honor_FLT_ROUNDS - if (rounding != 1) { - if (i < 0) { - /* Error is less than an ulp */ - if (!delta->x[0] && delta->wds <= 1) { - /* exact */ + if (rounding != 1) { + if (i < 0) { + /* Error is less than an ulp */ + if (!delta->x[0] && delta->wds <= 1) { + /* exact */ #ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - if (rounding) { - if (dsign) { - adj = 1.; - goto apply_adj; - } - } - else if (!dsign) { - adj = -1.; - if (!word1(rv) - && !(word0(rv) & Frac_mask)) { - y = word0(rv) & Exp_mask; + inexact = 0; +#endif + break; + } + if (rounding) { + if (dsign) { + adj = 1.; + goto apply_adj; + } + } + else if (!dsign) { + adj = -1.; + if (!word1(rv) + && !(word0(rv) & Frac_mask)) { + y = word0(rv) & Exp_mask; #ifdef Avoid_Underflow - if (!scale || y > 2*P*Exp_msk1) + if (!scale || y > 2*P*Exp_msk1) #else - if (y) + if (y) #endif - { - delta = lshift(delta,Log2P); - if (cmp(delta, bs) <= 0) - adj = -0.5; - } - } - apply_adj: + { + delta = lshift(delta,Log2P); + if (cmp(delta, bs) <= 0) { + adj = -0.5; + } + } + } +apply_adj: #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) - <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + if (scale && (y = word0(rv) & Exp_mask) + <= 2*P*Exp_msk1) { + word0(adj) += (2*P+1)*Exp_msk1 - y; + } #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= - P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - dval(rv) += adj*ulp(dval(rv)); - word0(rv) -= P*Exp_msk1; - } - else + if ((word0(rv) & Exp_mask) <= + P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + dval(rv) += adj*ulp(dval(rv)); + word0(rv) -= P*Exp_msk1; + } + else #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - dval(rv) += adj*ulp(dval(rv)); - } - break; - } - adj = ratio(delta, bs); - if (adj < 1.) - adj = 1.; - if (adj <= 0x7ffffffe) { - /* adj = rounding ? ceil(adj) : floor(adj); */ - y = adj; - if (y != adj) { - if (!((rounding>>1) ^ dsign)) - y++; - adj = y; - } - } + dval(rv) += adj*ulp(dval(rv)); + } + break; + } + adj = ratio(delta, bs); + if (adj < 1.) { + adj = 1.; + } + if (adj <= 0x7ffffffe) { + /* adj = rounding ? ceil(adj) : floor(adj); */ + y = adj; + if (y != adj) { + if (!((rounding>>1) ^ dsign)) { + y++; + } + adj = y; + } + } #ifdef Avoid_Underflow - if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - word0(adj) += (2*P+1)*Exp_msk1 - y; + if (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) { + word0(adj) += (2*P+1)*Exp_msk1 - y; + } #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - word0(rv) += P*Exp_msk1; - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - word0(rv) -= P*Exp_msk1; - goto cont; - } + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + word0(rv) += P*Exp_msk1; + adj *= ulp(dval(rv)); + if (dsign) { + dval(rv) += adj; + } + else { + dval(rv) -= adj; + } + word0(rv) -= P*Exp_msk1; + goto cont; + } #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - adj *= ulp(dval(rv)); - if (dsign) - dval(rv) += adj; - else - dval(rv) -= adj; - goto cont; - } + adj *= ulp(dval(rv)); + if (dsign) { + dval(rv) += adj; + } + else { + dval(rv) -= adj; + } + goto cont; + } #endif /*Honor_FLT_ROUNDS*/ - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask + if (i < 0) { + /* Error is less than half an ulp -- check for + * special case of mantissa a power of two. + */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask #ifdef IEEE_Arith #ifdef Avoid_Underflow - || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 + || (word0(rv) & Exp_mask) <= (2*P+1)*Exp_msk1 #else - || (word0(rv) & Exp_mask) <= Exp_msk1 + || (word0(rv) & Exp_mask) <= Exp_msk1 #endif #endif - ) { + ) { #ifdef SET_INEXACT - if (!delta->x[0] && delta->wds <= 1) - inexact = 0; + if (!delta->x[0] && delta->wds <= 1) { + inexact = 0; + } #endif - break; - } - if (!delta->x[0] && delta->wds <= 1) { - /* exact result */ + break; + } + if (!delta->x[0] && delta->wds <= 1) { + /* exact result */ #ifdef SET_INEXACT - inexact = 0; -#endif - break; - } - delta = lshift(delta,Log2P); - if (cmp(delta, bs) > 0) - goto drop_down; - break; - } - if (i == 0) { - /* exactly half-way between */ - if (dsign) { - if ((word0(rv) & Bndry_mask1) == Bndry_mask1 - && word1(rv) == ( + inexact = 0; +#endif + break; + } + delta = lshift(delta,Log2P); + if (cmp(delta, bs) > 0) { + goto drop_down; + } + break; + } + if (i == 0) { + /* exactly half-way between */ + if (dsign) { + if ((word0(rv) & Bndry_mask1) == Bndry_mask1 + && word1(rv) == ( #ifdef Avoid_Underflow - (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) - ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : + (scale && (y = word0(rv) & Exp_mask) <= 2*P*Exp_msk1) + ? (0xffffffff & (0xffffffff << (2*P+1-(y>>Exp_shift)))) : #endif - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(rv) = (word0(rv) & Exp_mask) - + Exp_msk1 + 0xffffffff)) { + /*boundary case -- increment exponent*/ + word0(rv) = (word0(rv) & Exp_mask) + + Exp_msk1 #ifdef IBM - | Exp_msk1 >> 4 + | Exp_msk1 >> 4 #endif - ; - word1(rv) = 0; + ; + word1(rv) = 0; #ifdef Avoid_Underflow - dsign = 0; -#endif - break; - } - } - else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { - drop_down: - /* boundary case -- decrement exponent */ + dsign = 0; +#endif + break; + } + } + else if (!(word0(rv) & Bndry_mask) && !word1(rv)) { +drop_down: + /* boundary case -- decrement exponent */ #ifdef Sudden_Underflow /*{{*/ - L = word0(rv) & Exp_mask; + L = word0(rv) & Exp_mask; #ifdef IBM - if (L < Exp_msk1) + if (L < Exp_msk1) #else #ifdef Avoid_Underflow - if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) + if (L <= (scale ? (2*P+1)*Exp_msk1 : Exp_msk1)) #else - if (L <= Exp_msk1) + if (L <= Exp_msk1) #endif /*Avoid_Underflow*/ #endif /*IBM*/ - goto undfl; - L -= Exp_msk1; + goto undfl; + L -= Exp_msk1; #else /*Sudden_Underflow}{*/ #ifdef Avoid_Underflow - if (scale) { - L = word0(rv) & Exp_mask; - if (L <= (2*P+1)*Exp_msk1) { - if (L > (P+2)*Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - goto undfl; - } - } + if (scale) { + L = word0(rv) & Exp_mask; + if (L <= (2*P+1)*Exp_msk1) { + if (L > (P+2)*Exp_msk1) + /* round even ==> */ + /* accept rv */ + { + break; + } + /* rv = smallest denormal */ + goto undfl; + } + } #endif /*Avoid_Underflow*/ - L = (word0(rv) & Exp_mask) - Exp_msk1; + L = (word0(rv) & Exp_mask) - Exp_msk1; #endif /*Sudden_Underflow}}*/ - word0(rv) = L | Bndry_mask1; - word1(rv) = 0xffffffff; + word0(rv) = L | Bndry_mask1; + word1(rv) = 0xffffffff; #ifdef IBM - goto cont; + goto cont; #else - break; + break; #endif - } + } #ifndef ROUND_BIASED - if (!(word1(rv) & LSB)) - break; + if (!(word1(rv) & LSB)) { + break; + } #endif - if (dsign) - dval(rv) += ulp(dval(rv)); + if (dsign) { + dval(rv) += ulp(dval(rv)); + } #ifndef ROUND_BIASED - else { - dval(rv) -= ulp(dval(rv)); + else { + dval(rv) -= ulp(dval(rv)); #ifndef Sudden_Underflow - if (!dval(rv)) - goto undfl; + if (!dval(rv)) { + goto undfl; + } #endif - } + } #ifdef Avoid_Underflow - dsign = 1 - dsign; + dsign = 1 - dsign; #endif #endif - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (word1(rv) || word0(rv) & Bndry_mask) { + break; + } + if ((aadj = ratio(delta, bs)) <= 2.) { + if (dsign) { + aadj = aadj1 = 1.; + } + else if (word1(rv) || word0(rv) & Bndry_mask) { #ifndef Sudden_Underflow - if (word1(rv) == Tiny1 && !word0(rv)) - goto undfl; -#endif - aadj = 1.; - aadj1 = -1.; - } - else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2./FLT_RADIX) - aadj = 1./FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } - else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; + if (word1(rv) == Tiny1 && !word0(rv)) { + goto undfl; + } +#endif + aadj = 1.; + aadj1 = -1.; + } + else { + /* special case -- power of FLT_RADIX to be */ + /* rounded down... */ + + if (aadj < 2./FLT_RADIX) { + aadj = 1./FLT_RADIX; + } + else { + aadj *= 0.5; + } + aadj1 = -aadj; + } + } + else { + aadj *= 0.5; + aadj1 = dsign ? aadj : -aadj; #ifdef Check_FLT_ROUNDS - switch(Rounding) { - case 2: /* towards +infinity */ - aadj1 -= 0.5; - break; - case 0: /* towards 0 */ - case 3: /* towards -infinity */ - aadj1 += 0.5; - } -#else - if (Flt_Rounds == 0) - aadj1 += 0.5; + switch(Rounding) { + case 2: /* towards +infinity */ + aadj1 -= 0.5; + break; + case 0: /* towards 0 */ + case 3: /* towards -infinity */ + aadj1 += 0.5; + } +#else + if (Flt_Rounds == 0) { + aadj1 += 0.5; + } #endif /*Check_FLT_ROUNDS*/ - } - y = word0(rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { - dval(rv0) = dval(rv); - word0(rv) -= P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - if ((word0(rv) & Exp_mask) >= - Exp_msk1*(DBL_MAX_EXP+Bias-P)) { - if (word0(rv0) == Big0 && word1(rv0) == Big1) - goto ovfl; - word0(rv) = Big0; - word1(rv) = Big1; - goto cont; - } - else - word0(rv) += P*Exp_msk1; - } - else { + } + y = word0(rv) & Exp_mask; + + /* Check for overflow */ + + if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { + dval(rv0) = dval(rv); + word0(rv) -= P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + if ((word0(rv) & Exp_mask) >= + Exp_msk1*(DBL_MAX_EXP+Bias-P)) { + if (word0(rv0) == Big0 && word1(rv0) == Big1) { + goto ovfl; + } + word0(rv) = Big0; + word1(rv) = Big1; + goto cont; + } + else { + word0(rv) += P*Exp_msk1; + } + } + else { #ifdef Avoid_Underflow - if (scale && y <= 2*P*Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = aadj) <= 0) - z = 1; - aadj = z; - aadj1 = dsign ? aadj : -aadj; - } - dval(aadj2) = aadj1; - word0(aadj2) += (2*P+1)*Exp_msk1 - y; - aadj1 = dval(aadj2); - } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + if (scale && y <= 2*P*Exp_msk1) { + if (aadj <= 0x7fffffff) { + if ((z = aadj) <= 0) { + z = 1; + } + aadj = z; + aadj1 = dsign ? aadj : -aadj; + } + dval(aadj2) = aadj1; + word0(aadj2) += (2*P+1)*Exp_msk1 - y; + aadj1 = dval(aadj2); + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; #else #ifdef Sudden_Underflow - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { - dval(rv0) = dval(rv); - word0(rv) += P*Exp_msk1; - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) { + dval(rv0) = dval(rv); + word0(rv) += P*Exp_msk1; + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; #ifdef IBM - if ((word0(rv) & Exp_mask) < P*Exp_msk1) -#else - if ((word0(rv) & Exp_mask) <= P*Exp_msk1) -#endif - { - if (word0(rv0) == Tiny0 - && word1(rv0) == Tiny1) - goto undfl; - word0(rv) = Tiny0; - word1(rv) = Tiny1; - goto cont; - } - else - word0(rv) -= P*Exp_msk1; - } - else { - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; - } + if ((word0(rv) & Exp_mask) < P*Exp_msk1) +#else + if ((word0(rv) & Exp_mask) <= P*Exp_msk1) +#endif + { + if (word0(rv0) == Tiny0 + && word1(rv0) == Tiny1) { + goto undfl; + } + word0(rv) = Tiny0; + word1(rv) = Tiny1; + goto cont; + } + else { + word0(rv) -= P*Exp_msk1; + } + } + else { + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; + } #else /*Sudden_Underflow*/ - /* Compute adj so that the IEEE rounding rules will - * correctly round rv + adj in some half-way cases. - * If rv * ulp(rv) is denormalized (i.e., - * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid - * trouble from bits lost to denormalization; - * example: 1.2e-307 . - */ - if (y <= (P-1)*Exp_msk1 && aadj > 1.) { - aadj1 = (double)(int)(aadj + 0.5); - if (!dsign) - aadj1 = -aadj1; - } - adj = aadj1 * ulp(dval(rv)); - dval(rv) += adj; + /* Compute adj so that the IEEE rounding rules will + * correctly round rv + adj in some half-way cases. + * If rv * ulp(rv) is denormalized (i.e., + * y <= (P-1)*Exp_msk1), we must adjust aadj to avoid + * trouble from bits lost to denormalization; + * example: 1.2e-307 . + */ + if (y <= (P-1)*Exp_msk1 && aadj > 1.) { + aadj1 = (double)(int)(aadj + 0.5); + if (!dsign) { + aadj1 = -aadj1; + } + } + adj = aadj1 * ulp(dval(rv)); + dval(rv) += adj; #endif /*Sudden_Underflow*/ #endif /*Avoid_Underflow*/ - } - z = word0(rv) & Exp_mask; + } + z = word0(rv) & Exp_mask; #ifndef SET_INEXACT #ifdef Avoid_Underflow - if (!scale) -#endif - if (y == z) { - /* Can we stop now? */ - L = (Long)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || word1(rv) || word0(rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } - else if (aadj < .4999999/FLT_RADIX) - break; - } -#endif - cont: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(delta); - } + if (!scale) +#endif + if (y == z) { + /* Can we stop now? */ + L = (Long)aadj; + aadj -= L; + /* The tolerances below are conservative. */ + if (dsign || word1(rv) || word0(rv) & Bndry_mask) { + if (aadj < .4999999 || aadj > .5000001) { + break; + } + } + else if (aadj < .4999999/FLT_RADIX) { + break; + } + } +#endif +cont: + Bfree(bb); + Bfree(bd); + Bfree(bs); + Bfree(delta); +} #ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(rv0) = Exp_1 + (70 << Exp_shift); - word1(rv0) = 0; - dval(rv0) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); +if (inexact) { + if (!oldinexact) { + word0(rv0) = Exp_1 + (70 << Exp_shift); + word1(rv0) = 0; + dval(rv0) += 1.; + } +} +else if (!oldinexact) { + clear_inexact(); +} #endif #ifdef Avoid_Underflow - if (scale) { - word0(rv0) = Exp_1 - 2*P*Exp_msk1; - word1(rv0) = 0; - dval(rv) *= dval(rv0); +if (scale) { + word0(rv0) = Exp_1 - 2*P*Exp_msk1; + word1(rv0) = 0; + dval(rv) *= dval(rv0); #ifndef NO_ERRNO - /* try to avoid the bug of testing an 8087 register value */ - if (word0(rv) == 0 && word1(rv) == 0) - PR_SetError(PR_RANGE_ERROR, 0); + /* try to avoid the bug of testing an 8087 register value */ + if (word0(rv) == 0 && word1(rv) == 0) { + PR_SetError(PR_RANGE_ERROR, 0); + } #endif - } +} #endif /* Avoid_Underflow */ #ifdef SET_INEXACT - if (inexact && !(word0(rv) & Exp_mask)) { - /* set underflow bit */ - dval(rv0) = 1e-300; - dval(rv0) *= dval(rv0); - } -#endif - retfree: - Bfree(bb); - Bfree(bd); - Bfree(bs); - Bfree(bd0); - Bfree(delta); - ret: - if (se) - *se = (char *)s; - return sign ? -dval(rv) : dval(rv); - } - - static int +if (inexact && !(word0(rv) & Exp_mask)) { + /* set underflow bit */ + dval(rv0) = 1e-300; + dval(rv0) *= dval(rv0); +} +#endif +retfree: +Bfree(bb); +Bfree(bd); +Bfree(bs); +Bfree(bd0); +Bfree(delta); +ret: +if (se) { + *se = (char *)s; +} +return sign ? -dval(rv) : dval(rv); +} + +static int quorem #ifdef KR_headers - (b, S) Bigint *b, *S; +(b, S) Bigint *b, *S; #else - (Bigint *b, Bigint *S) +(Bigint *b, Bigint *S) #endif { - int n; - ULong *bx, *bxe, q, *sx, *sxe; + int n; + ULong *bx, *bxe, q, *sx, *sxe; #ifdef ULLong - ULLong borrow, carry, y, ys; + ULLong borrow, carry, y, ys; #else - ULong borrow, carry, y, ys; + ULong borrow, carry, y, ys; #ifdef Pack_32 - ULong si, z, zs; + ULong si, z, zs; #endif #endif - n = S->wds; + n = S->wds; #ifdef DEBUG - /*debug*/ if (b->wds > n) - /*debug*/ Bug("oversize b in quorem"); -#endif - if (b->wds < n) - return 0; - sx = S->x; - sxe = sx + --n; - bx = b->x; - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ + /*debug*/ if (b->wds > n) + /*debug*/{ + Bug("oversize b in quorem"); + } +#endif + if (b->wds < n) { + return 0; + } + sx = S->x; + sxe = sx + --n; + bx = b->x; + bxe = bx + n; + q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ #ifdef DEBUG - /*debug*/ if (q > 9) - /*debug*/ Bug("oversized quotient in quorem"); + /*debug*/ if (q > 9) + /*debug*/{ + Bug("oversized quotient in quorem"); + } #endif - if (q) { - borrow = 0; - carry = 0; - do { + if (q) { + borrow = 0; + carry = 0; + do { #ifdef ULLong - ys = *sx++ * (ULLong)q + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + ys = *sx++ * (ULLong)q + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; #else #ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ * q + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - if (!*bxe) { - bx = b->x; - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b->x; - sx = S->x; - do { + si = *sx++; + ys = (si & 0xffff) * q + carry; + zs = (si >> 16) * q + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ * q + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + if (!*bxe) { + bx = b->x; + while(--bxe > bx && !*bxe) { + --n; + } + b->wds = n; + } + } + if (cmp(b, S) >= 0) { + q++; + borrow = 0; + carry = 0; + bx = b->x; + sx = S->x; + do { #ifdef ULLong - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & FFFFFFFF) - borrow; - borrow = y >> 32 & (ULong)1; - *bx++ = y & FFFFFFFF; + ys = *sx++ + carry; + carry = ys >> 32; + y = *bx - (ys & FFFFFFFF) - borrow; + borrow = y >> 32 & (ULong)1; + *bx++ = y & FFFFFFFF; #else #ifdef Pack_32 - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - Storeinc(bx, z, y); -#else - ys = *sx++ + carry; - carry = ys >> 16; - y = *bx - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - *bx++ = y & 0xffff; -#endif -#endif - } - while(sx <= sxe); - bx = b->x; - bxe = bx + n; - if (!*bxe) { - while(--bxe > bx && !*bxe) - --n; - b->wds = n; - } - } - return q; - } + si = *sx++; + ys = (si & 0xffff) + carry; + zs = (si >> 16) + (ys >> 16); + carry = zs >> 16; + y = (*bx & 0xffff) - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + z = (*bx >> 16) - (zs & 0xffff) - borrow; + borrow = (z & 0x10000) >> 16; + Storeinc(bx, z, y); +#else + ys = *sx++ + carry; + carry = ys >> 16; + y = *bx - (ys & 0xffff) - borrow; + borrow = (y & 0x10000) >> 16; + *bx++ = y & 0xffff; +#endif +#endif + } + while(sx <= sxe); + bx = b->x; + bxe = bx + n; + if (!*bxe) { + while(--bxe > bx && !*bxe) { + --n; + } + b->wds = n; + } + } + return q; +} #ifndef MULTIPLE_THREADS - static char *dtoa_result; +static char *dtoa_result; #endif - static char * +static char * #ifdef KR_headers rv_alloc(i) int i; #else rv_alloc(int i) #endif { - int j, k, *r; - - j = sizeof(ULong); - for(k = 0; - sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; - j <<= 1) - k++; - r = (int*)Balloc(k); - *r = k; - return + int j, k, *r; + + j = sizeof(ULong); + for(k = 0; + sizeof(Bigint) - sizeof(ULong) - sizeof(int) + j <= i; + j <<= 1) { + k++; + } + r = (int*)Balloc(k); + *r = k; + return #ifndef MULTIPLE_THREADS - dtoa_result = + dtoa_result = #endif - (char *)(r+1); - } + (char *)(r+1); +} - static char * +static char * #ifdef KR_headers nrv_alloc(s, rve, n) char *s, **rve; int n; #else nrv_alloc(char *s, char **rve, int n) #endif { - char *rv, *t; + char *rv, *t; - t = rv = rv_alloc(n); - while(*t = *s++) t++; - if (rve) - *rve = t; - return rv; - } + t = rv = rv_alloc(n); + while(*t = *s++) { + t++; + } + if (rve) { + *rve = t; + } + return rv; +} /* freedtoa(s) must be used to free values s returned by dtoa * when MULTIPLE_THREADS is #defined. It should be used in all cases, @@ -2658,21 +2802,22 @@ nrv_alloc(char *s, char **rve, int n) * when MULTIPLE_THREADS is not defined. */ - static void +static void #ifdef KR_headers freedtoa(s) char *s; #else freedtoa(char *s) #endif { - Bigint *b = (Bigint *)((int *)s - 1); - b->maxwds = 1 << (b->k = *(int*)b); - Bfree(b); + Bigint *b = (Bigint *)((int *)s - 1); + b->maxwds = 1 << (b->k = *(int*)b); + Bfree(b); #ifndef MULTIPLE_THREADS - if (s == dtoa_result) - dtoa_result = 0; + if (s == dtoa_result) { + dtoa_result = 0; + } #endif - } +} /* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. * @@ -2680,729 +2825,770 @@ freedtoa(char *s) * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. * * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the Long - * calculation. + * 1. Rather than iterating, we use a simple numeric overestimate + * to determine k = floor(log10(d)). We scale relevant + * quantities using O(log2(k)) rather than O(k) multiplications. + * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't + * try to generate digits strictly left to right. Instead, we + * compute with fewer bits and propagate the carry if necessary + * when rounding the final digit up. This is often faster. + * 3. Under the assumption that input will be rounded nearest, + * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. + * That is, we allow equality in stopping tests when the + * round-nearest rule will give the same floating-point value + * as would satisfaction of the stopping test with strict + * inequality. + * 4. We remove common factors of powers of 2 from relevant + * quantities. + * 5. When converting floating-point integers less than 1e16, + * we use floating-point arithmetic rather than resorting + * to multiple-precision integers. + * 6. When asked to produce fewer than 15 digits, we first try + * to get by with floating-point arithmetic; we resort to + * multiple-precision integer arithmetic only if we cannot + * guarantee that the floating-point calculation has given + * the correctly rounded result. For k requested digits and + * "uniformly" distributed input, the probability is + * something like 10^(k-15) that we must resort to the Long + * calculation. */ - static char * +static char * dtoa #ifdef KR_headers - (dd, mode, ndigits, decpt, sign, rve) - double dd; int mode, ndigits, *decpt, *sign; char **rve; +(dd, mode, ndigits, decpt, sign, rve) +double dd; int mode, ndigits, *decpt, *sign; char **rve; #else - (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) +(double dd, int mode, int ndigits, int *decpt, int *sign, char **rve) #endif { - /* Arguments ndigits, decpt, sign are similar to those - of ecvt and fcvt; trailing zeros are suppressed from - the returned string. If not null, *rve is set to point - to the end of the return value. If d is +-Infinity or NaN, - then *decpt is set to 9999. - - mode: - 0 ==> shortest string that yields d when read in - and rounded to nearest. - 1 ==> like 0, but with Steele & White stopping rule; - e.g. with IEEE P754 arithmetic , mode 0 gives - 1e23 whereas mode 1 gives 9.999999999999999e22. - 2 ==> max(1,ndigits) significant digits. This gives a - return value similar to that of ecvt, except - that trailing zeros are suppressed. - 3 ==> through ndigits past the decimal point. This - gives a return value similar to that from fcvt, - except that trailing zeros are suppressed, and - ndigits can be negative. - 4,5 ==> similar to 2 and 3, respectively, but (in - round-nearest mode) with the tests of mode 0 to - possibly return a shorter string that rounds to d. - With IEEE arithmetic and compilation with - -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same - as modes 2 and 3 when FLT_ROUNDS != 1. - 6-9 ==> Debugging modes similar to mode - 4: don't try - fast floating-point estimate (if applicable). - - Values of mode other than 0-9 are treated as mode 0. - - Sufficient space is allocated to the return value - to hold the suppressed trailing zeros. - */ - - int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, - j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, - spec_case, try_quick; - Long L; + /* Arguments ndigits, decpt, sign are similar to those + of ecvt and fcvt; trailing zeros are suppressed from + the returned string. If not null, *rve is set to point + to the end of the return value. If d is +-Infinity or NaN, + then *decpt is set to 9999. + + mode: + 0 ==> shortest string that yields d when read in + and rounded to nearest. + 1 ==> like 0, but with Steele & White stopping rule; + e.g. with IEEE P754 arithmetic , mode 0 gives + 1e23 whereas mode 1 gives 9.999999999999999e22. + 2 ==> max(1,ndigits) significant digits. This gives a + return value similar to that of ecvt, except + that trailing zeros are suppressed. + 3 ==> through ndigits past the decimal point. This + gives a return value similar to that from fcvt, + except that trailing zeros are suppressed, and + ndigits can be negative. + 4,5 ==> similar to 2 and 3, respectively, but (in + round-nearest mode) with the tests of mode 0 to + possibly return a shorter string that rounds to d. + With IEEE arithmetic and compilation with + -DHonor_FLT_ROUNDS, modes 4 and 5 behave the same + as modes 2 and 3 when FLT_ROUNDS != 1. + 6-9 ==> Debugging modes similar to mode - 4: don't try + fast floating-point estimate (if applicable). + + Values of mode other than 0-9 are treated as mode 0. + + Sufficient space is allocated to the return value + to hold the suppressed trailing zeros. + */ + + int bbits, b2, b5, be, dig, i, ieps, ilim, ilim0, ilim1, + j, j1, k, k0, k_check, leftright, m2, m5, s2, s5, + spec_case, try_quick; + Long L; #ifndef Sudden_Underflow - int denorm; - ULong x; + int denorm; + ULong x; #endif - Bigint *b, *b1, *delta, *mlo, *mhi, *S; - U d, d2, eps; - double ds; - char *s, *s0; + Bigint *b, *b1, *delta, *mlo, *mhi, *S; + U d, d2, eps; + double ds; + char *s, *s0; #ifdef Honor_FLT_ROUNDS - int rounding; + int rounding; #endif #ifdef SET_INEXACT - int inexact, oldinexact; + int inexact, oldinexact; #endif #ifndef MULTIPLE_THREADS - if (dtoa_result) { - freedtoa(dtoa_result); - dtoa_result = 0; - } + if (dtoa_result) { + freedtoa(dtoa_result); + dtoa_result = 0; + } #endif - dval(d) = dd; - if (word0(d) & Sign_bit) { - /* set sign for everything, including 0's and NaNs */ - *sign = 1; - word0(d) &= ~Sign_bit; /* clear sign bit */ - } - else - *sign = 0; + dval(d) = dd; + if (word0(d) & Sign_bit) { + /* set sign for everything, including 0's and NaNs */ + *sign = 1; + word0(d) &= ~Sign_bit; /* clear sign bit */ + } + else { + *sign = 0; + } #if defined(IEEE_Arith) + defined(VAX) #ifdef IEEE_Arith - if ((word0(d) & Exp_mask) == Exp_mask) + if ((word0(d) & Exp_mask) == Exp_mask) #else - if (word0(d) == 0x8000) + if (word0(d) == 0x8000) #endif - { - /* Infinity or NaN */ - *decpt = 9999; + { + /* Infinity or NaN */ + *decpt = 9999; #ifdef IEEE_Arith - if (!word1(d) && !(word0(d) & 0xfffff)) - return nrv_alloc("Infinity", rve, 8); + if (!word1(d) && !(word0(d) & 0xfffff)) { + return nrv_alloc("Infinity", rve, 8); + } #endif - return nrv_alloc("NaN", rve, 3); - } + return nrv_alloc("NaN", rve, 3); + } #endif #ifdef IBM - dval(d) += 0; /* normalize */ + dval(d) += 0; /* normalize */ #endif - if (!dval(d)) { - *decpt = 1; - return nrv_alloc("0", rve, 1); - } + if (!dval(d)) { + *decpt = 1; + return nrv_alloc("0", rve, 1); + } #ifdef SET_INEXACT - try_quick = oldinexact = get_inexact(); - inexact = 1; + try_quick = oldinexact = get_inexact(); + inexact = 1; #endif #ifdef Honor_FLT_ROUNDS - if ((rounding = Flt_Rounds) >= 2) { - if (*sign) - rounding = rounding == 2 ? 0 : 2; - else - if (rounding != 2) - rounding = 0; - } + if ((rounding = Flt_Rounds) >= 2) { + if (*sign) { + rounding = rounding == 2 ? 0 : 2; + } + else if (rounding != 2) { + rounding = 0; + } + } #endif - b = d2b(dval(d), &be, &bbits); + b = d2b(dval(d), &be, &bbits); #ifdef Sudden_Underflow - i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); + i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1)); #else - if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { + if (i = (int)(word0(d) >> Exp_shift1 & (Exp_mask>>Exp_shift1))) { #endif - dval(d2) = dval(d); - word0(d2) &= Frac_mask1; - word0(d2) |= Exp_11; + dval(d2) = dval(d); + word0(d2) &= Frac_mask1; + word0(d2) |= Exp_11; #ifdef IBM - if (j = 11 - hi0bits(word0(d2) & Frac_mask)) - dval(d2) /= 1 << j; -#endif - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; + if (j = 11 - hi0bits(word0(d2) & Frac_mask)) { + dval(d2) /= 1 << j; + } +#endif + + /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 + * log10(x) = log(x) / log(10) + * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) + * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) + * + * This suggests computing an approximation k to log10(d) by + * + * k = (i - Bias)*0.301029995663981 + * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); + * + * We want k to be too large rather than too small. + * The error in the first-order Taylor series approximation + * is in our favor, so we just round up the constant enough + * to compensate for any error in the multiplication of + * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, + * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, + * adding 1e-13 to the constant term more than suffices. + * Hence we adjust the constant term to 0.1760912590558. + * (We could get a more accurate k by invoking log10, + * but this is probably not worthwhile.) + */ + + i -= Bias; #ifdef IBM - i <<= 2; - i += j; + i <<= 2; + i += j; #endif #ifndef Sudden_Underflow - denorm = 0; - } - else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P-1) - 1); - x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 - : word1(d) << 32 - i; - dval(d2) = x; - word0(d2) -= 31*Exp_msk1; /* adjust exponent */ - i -= (Bias + (P-1) - 1) + 1; - denorm = 1; - } -#endif - ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(d) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } - else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } - else { - b2 -= k; - b5 = -k; - s5 = 0; - } - if (mode < 0 || mode > 9) - mode = 0; + denorm = 0; +} +else { + /* d is denormalized */ + + i = bbits + be + (Bias + (P-1) - 1); + x = i > 32 ? word0(d) << 64 - i | word1(d) >> i - 32 + : word1(d) << 32 - i; + dval(d2) = x; + word0(d2) -= 31*Exp_msk1; /* adjust exponent */ + i -= (Bias + (P-1) - 1) + 1; + denorm = 1; +} +#endif +ds = (dval(d2)-1.5)*0.289529654602168 + 0.1760912590558 + i*0.301029995663981; +k = (int)ds; +if (ds < 0. && ds != k) { + k--; /* want k = floor(ds) */ +} +k_check = 1; +if (k >= 0 && k <= Ten_pmax) { + if (dval(d) < tens[k]) { + k--; + } + k_check = 0; +} +j = bbits - i - 1; +if (j >= 0) { + b2 = 0; + s2 = j; +} +else { + b2 = -j; + s2 = 0; +} +if (k >= 0) { + b5 = 0; + s5 = k; + s2 += k; +} +else { + b2 -= k; + b5 = -k; + s5 = 0; +} +if (mode < 0 || mode > 9) { + mode = 0; +} #ifndef SET_INEXACT #ifdef Check_FLT_ROUNDS - try_quick = Rounding == 1; +try_quick = Rounding == 1; #else - try_quick = 1; +try_quick = 1; #endif #endif /*SET_INEXACT*/ - if (mode > 5) { - mode -= 4; - try_quick = 0; - } - leftright = 1; - switch(mode) { - case 0: - case 1: - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - break; - case 2: - leftright = 0; - /* no break */ - case 4: - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - break; - case 3: - leftright = 0; - /* no break */ - case 5: - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - s = s0 = rv_alloc(i); +if (mode > 5) { + mode -= 4; + try_quick = 0; +} +leftright = 1; +switch(mode) { +case 0: +case 1: + ilim = ilim1 = -1; + i = 18; + ndigits = 0; + break; +case 2: + leftright = 0; +/* no break */ +case 4: + if (ndigits <= 0) { + ndigits = 1; + } + ilim = ilim1 = i = ndigits; + break; +case 3: + leftright = 0; +/* no break */ +case 5: + i = ndigits + k + 1; + ilim = i; + ilim1 = i - 1; + if (i <= 0) { + i = 1; + } +} +s = s0 = rv_alloc(i); #ifdef Honor_FLT_ROUNDS - if (mode > 1 && rounding != 1) - leftright = 0; -#endif - - if (ilim >= 0 && ilim <= Quick_max && try_quick) { - - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(d2) = dval(d); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k&0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(d) /= bigtens[n_bigtens-1]; - ieps++; - } - for(; j; j >>= 1, i++) - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - dval(d) /= ds; - } - else if (j1 = -k) { - dval(d) *= tens[j1 & 0xf]; - for(j = j1 >> 4; j; j >>= 1, i++) - if (j & 1) { - ieps++; - dval(d) *= bigtens[i]; - } - } - if (k_check && dval(d) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fast_failed; - ilim = ilim1; - k--; - dval(d) *= 10.; - ieps++; - } - dval(eps) = ieps*dval(d) + 7.; - word0(eps) -= (P-1)*Exp_msk1; - if (ilim == 0) { - S = mhi = 0; - dval(d) -= 5.; - if (dval(d) > dval(eps)) - goto one_digit; - if (dval(d) < -dval(eps)) - goto no_digits; - goto fast_failed; - } +if (mode > 1 && rounding != 1) { + leftright = 0; +} +#endif + +if (ilim >= 0 && ilim <= Quick_max && try_quick) { + + /* Try to get by with floating-point arithmetic. */ + + i = 0; + dval(d2) = dval(d); + k0 = k; + ilim0 = ilim; + ieps = 2; /* conservative */ + if (k > 0) { + ds = tens[k&0xf]; + j = k >> 4; + if (j & Bletch) { + /* prevent overflows */ + j &= Bletch - 1; + dval(d) /= bigtens[n_bigtens-1]; + ieps++; + } + for(; j; j >>= 1, i++) + if (j & 1) { + ieps++; + ds *= bigtens[i]; + } + dval(d) /= ds; + } + else if (j1 = -k) { + dval(d) *= tens[j1 & 0xf]; + for(j = j1 >> 4; j; j >>= 1, i++) + if (j & 1) { + ieps++; + dval(d) *= bigtens[i]; + } + } + if (k_check && dval(d) < 1. && ilim > 0) { + if (ilim1 <= 0) { + goto fast_failed; + } + ilim = ilim1; + k--; + dval(d) *= 10.; + ieps++; + } + dval(eps) = ieps*dval(d) + 7.; + word0(eps) -= (P-1)*Exp_msk1; + if (ilim == 0) { + S = mhi = 0; + dval(d) -= 5.; + if (dval(d) > dval(eps)) { + goto one_digit; + } + if (dval(d) < -dval(eps)) { + goto no_digits; + } + goto fast_failed; + } #ifndef No_leftright - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(eps) = 0.5/tens[ilim-1] - dval(eps); - for(i = 0;;) { - L = dval(d); - dval(d) -= L; - *s++ = '0' + (int)L; - if (dval(d) < dval(eps)) - goto ret1; - if (1. - dval(d) < dval(eps)) - goto bump_up; - if (++i >= ilim) - break; - dval(eps) *= 10.; - dval(d) *= 10.; - } - } - else { -#endif - /* Generate ilim digits, then fix them up. */ - dval(eps) *= tens[ilim-1]; - for(i = 1;; i++, dval(d) *= 10.) { - L = (Long)(dval(d)); - if (!(dval(d) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(d) > 0.5 + dval(eps)) - goto bump_up; - else if (dval(d) < 0.5 - dval(eps)) { - while(*--s == '0'); - s++; - goto ret1; - } - break; - } - } + if (leftright) { + /* Use Steele & White method of only + * generating digits needed. + */ + dval(eps) = 0.5/tens[ilim-1] - dval(eps); + for(i = 0;;) { + L = dval(d); + dval(d) -= L; + *s++ = '0' + (int)L; + if (dval(d) < dval(eps)) { + goto ret1; + } + if (1. - dval(d) < dval(eps)) { + goto bump_up; + } + if (++i >= ilim) { + break; + } + dval(eps) *= 10.; + dval(d) *= 10.; + } + } + else { +#endif + /* Generate ilim digits, then fix them up. */ + dval(eps) *= tens[ilim-1]; + for(i = 1;; i++, dval(d) *= 10.) { + L = (Long)(dval(d)); + if (!(dval(d) -= L)) { + ilim = i; + } + *s++ = '0' + (int)L; + if (i == ilim) { + if (dval(d) > 0.5 + dval(eps)) { + goto bump_up; + } + else if (dval(d) < 0.5 - dval(eps)) { + while(*--s == '0'); + s++; + goto ret1; + } + break; + } + } #ifndef No_leftright - } -#endif - fast_failed: - s = s0; - dval(d) = dval(d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S = mhi = 0; - if (ilim < 0 || dval(d) <= 5*ds) - goto no_digits; - goto one_digit; - } - for(i = 1; i <= k+1; i++, dval(d) *= 10.) { - L = (Long)(dval(d) / ds); - dval(d) -= L*ds; + } +#endif +fast_failed: + s = s0; + dval(d) = dval(d2); + k = k0; + ilim = ilim0; +} + +/* Do we have a "small" integer? */ + +if (be >= 0 && k <= Int_max) { + /* Yes. */ + ds = tens[k]; + if (ndigits < 0 && ilim <= 0) { + S = mhi = 0; + if (ilim < 0 || dval(d) <= 5*ds) { + goto no_digits; + } + goto one_digit; + } + for(i = 1; i <= k+1; i++, dval(d) *= 10.) { + L = (Long)(dval(d) / ds); + dval(d) -= L*ds; #ifdef Check_FLT_ROUNDS - /* If FLT_ROUNDS == 2, L will usually be high by 1 */ - if (dval(d) < 0) { - L--; - dval(d) += ds; - } -#endif - *s++ = '0' + (int)L; - if (!dval(d)) { + /* If FLT_ROUNDS == 2, L will usually be high by 1 */ + if (dval(d) < 0) { + L--; + dval(d) += ds; + } +#endif + *s++ = '0' + (int)L; + if (!dval(d)) { #ifdef SET_INEXACT - inexact = 0; + inexact = 0; #endif - break; - } - if (i == ilim) { + break; + } + if (i == ilim) { #ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(rounding) { - case 0: goto ret1; - case 2: goto bump_up; - } -#endif - dval(d) += dval(d); - if (dval(d) > ds || dval(d) == ds && L & 1) { - bump_up: - while(*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret1; - } - - m2 = b2; - m5 = b5; - mhi = mlo = 0; - if (leftright) { - i = + if (mode > 1) + switch(rounding) { + case 0: goto ret1; + case 2: goto bump_up; + } +#endif + dval(d) += dval(d); + if (dval(d) > ds || dval(d) == ds && L & 1) { +bump_up: + while(*--s == '9') + if (s == s0) { + k++; + *s = '0'; + break; + } + ++*s++; + } + break; + } + } + goto ret1; +} + +m2 = b2; +m5 = b5; +mhi = mlo = 0; +if (leftright) { + i = #ifndef Sudden_Underflow - denorm ? be + (Bias + (P-1) - 1 + 1) : + denorm ? be + (Bias + (P-1) - 1 + 1) : #endif #ifdef IBM - 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); -#else - 1 + P - bbits; -#endif - b2 += i; - s2 += i; - mhi = i2b(1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - mhi = pow5mult(mhi, m5); - b1 = mult(mhi, b); - Bfree(b); - b = b1; - } - if (j = b5 - m5) - b = pow5mult(b, j); - } - else - b = pow5mult(b, b5); - } - S = i2b(1); - if (s5 > 0) - S = pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((mode < 2 || leftright) + 1 + 4*P - 3 - bbits + ((bbits + be - 1) & 3); +#else + 1 + P - bbits; +#endif + b2 += i; + s2 += i; + mhi = i2b(1); +} +if (m2 > 0 && s2 > 0) { + i = m2 < s2 ? m2 : s2; + b2 -= i; + m2 -= i; + s2 -= i; +} +if (b5 > 0) { + if (leftright) { + if (m5 > 0) { + mhi = pow5mult(mhi, m5); + b1 = mult(mhi, b); + Bfree(b); + b = b1; + } + if (j = b5 - m5) { + b = pow5mult(b, j); + } + } + else { + b = pow5mult(b, b5); + } +} +S = i2b(1); +if (s5 > 0) { + S = pow5mult(S, s5); +} + +/* Check for special case that d is a normalized power of 2. */ + +spec_case = 0; +if ((mode < 2 || leftright) #ifdef Honor_FLT_ROUNDS - && rounding == 1 + && rounding == 1 #endif - ) { - if (!word1(d) && !(word0(d) & Bndry_mask) + ) { + if (!word1(d) && !(word0(d) & Bndry_mask) #ifndef Sudden_Underflow - && word0(d) & (Exp_mask & ~Exp_msk1) -#endif - ) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ + && word0(d) & (Exp_mask & ~Exp_msk1) +#endif + ) { + /* The special case */ + b2 += Log2P; + s2 += Log2P; + spec_case = 1; + } +} + +/* Arrange for convenient computation of quotients: + * shift left if necessary so divisor has 4 leading 0 bits. + * + * Perhaps we should just compute leading 28 bits of S once + * and for all and pass them and a shift to quorem, so it + * can do shifts and ors to compute the numerator for q. + */ #ifdef Pack_32 - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) - i = 32 - i; -#else - if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) - i = 16 - i; -#endif - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } - else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - b = lshift(b, b2); - if (s2 > 0) - S = lshift(S, s2); - if (k_check) { - if (cmp(b,S) < 0) { - k--; - b = multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - mhi = multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && (mode == 3 || mode == 5)) { - if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { - /* no digits, fcvt style */ - no_digits: - k = -1 - ndigits; - goto ret; - } - one_digit: - *s++ = '1'; - k++; - goto ret; - } - if (leftright) { - if (m2 > 0) - mhi = lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) { - mhi = Balloc(mhi->k); - Bcopy(mhi, mlo); - mhi = lshift(mhi, Log2P); - } - - for(i = 1;;i++) { - dig = quorem(b,S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - delta = diff(S, mhi); - j1 = delta->sign ? 1 : cmp(b, delta); - Bfree(delta); +if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0x1f) { + i = 32 - i; +} +#else +if (i = ((s5 ? 32 - hi0bits(S->x[S->wds-1]) : 1) + s2) & 0xf) { + i = 16 - i; +} +#endif +if (i > 4) { + i -= 4; + b2 += i; + m2 += i; + s2 += i; +} +else if (i < 4) { + i += 28; + b2 += i; + m2 += i; + s2 += i; +} +if (b2 > 0) { + b = lshift(b, b2); +} +if (s2 > 0) { + S = lshift(S, s2); +} +if (k_check) { + if (cmp(b,S) < 0) { + k--; + b = multadd(b, 10, 0); /* we botched the k estimate */ + if (leftright) { + mhi = multadd(mhi, 10, 0); + } + ilim = ilim1; + } +} +if (ilim <= 0 && (mode == 3 || mode == 5)) { + if (ilim < 0 || cmp(b,S = multadd(S,5,0)) <= 0) { + /* no digits, fcvt style */ +no_digits: + k = -1 - ndigits; + goto ret; + } +one_digit: + *s++ = '1'; + k++; + goto ret; +} +if (leftright) { + if (m2 > 0) { + mhi = lshift(mhi, m2); + } + + /* Compute mlo -- check for special case + * that d is a normalized power of 2. + */ + + mlo = mhi; + if (spec_case) { + mhi = Balloc(mhi->k); + Bcopy(mhi, mlo); + mhi = lshift(mhi, Log2P); + } + + for(i = 1;; i++) { + dig = quorem(b,S) + '0'; + /* Do we yet have the shortest decimal string + * that will round to d? + */ + j = cmp(b, mlo); + delta = diff(S, mhi); + j1 = delta->sign ? 1 : cmp(b, delta); + Bfree(delta); #ifndef ROUND_BIASED - if (j1 == 0 && mode != 1 && !(word1(d) & 1) + if (j1 == 0 && mode != 1 && !(word1(d) & 1) #ifdef Honor_FLT_ROUNDS - && rounding >= 1 + && rounding >= 1 #endif - ) { - if (dig == '9') - goto round_9_up; - if (j > 0) - dig++; + ) { + if (dig == '9') { + goto round_9_up; + } + if (j > 0) { + dig++; + } #ifdef SET_INEXACT - else if (!b->x[0] && b->wds <= 1) - inexact = 0; + else if (!b->x[0] && b->wds <= 1) { + inexact = 0; + } #endif - *s++ = dig; - goto ret; - } + *s++ = dig; + goto ret; + } #endif - if (j < 0 || j == 0 && mode != 1 + if (j < 0 || j == 0 && mode != 1 #ifndef ROUND_BIASED - && !(word1(d) & 1) + && !(word1(d) & 1) #endif - ) { - if (!b->x[0] && b->wds <= 1) { + ) { + if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT - inexact = 0; + inexact = 0; #endif - goto accept_dig; - } + goto accept_dig; + } #ifdef Honor_FLT_ROUNDS - if (mode > 1) - switch(rounding) { - case 0: goto accept_dig; - case 2: goto keep_dig; - } + if (mode > 1) + switch(rounding) { + case 0: goto accept_dig; + case 2: goto keep_dig; + } #endif /*Honor_FLT_ROUNDS*/ - if (j1 > 0) { - b = lshift(b, 1); - j1 = cmp(b, S); - if ((j1 > 0 || j1 == 0 && dig & 1) - && dig++ == '9') - goto round_9_up; - } - accept_dig: - *s++ = dig; - goto ret; - } - if (j1 > 0) { + if (j1 > 0) { + b = lshift(b, 1); + j1 = cmp(b, S); + if ((j1 > 0 || j1 == 0 && dig & 1) + && dig++ == '9') { + goto round_9_up; + } + } +accept_dig: + *s++ = dig; + goto ret; + } + if (j1 > 0) { #ifdef Honor_FLT_ROUNDS - if (!rounding) - goto accept_dig; -#endif - if (dig == '9') { /* possible if i == 1 */ - round_9_up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } + if (!rounding) { + goto accept_dig; + } +#endif + if (dig == '9') { /* possible if i == 1 */ +round_9_up: + *s++ = '9'; + goto roundoff; + } + *s++ = dig + 1; + goto ret; + } #ifdef Honor_FLT_ROUNDS - keep_dig: -#endif - *s++ = dig; - if (i == ilim) - break; - b = multadd(b, 10, 0); - if (mlo == mhi) - mlo = mhi = multadd(mhi, 10, 0); - else { - mlo = multadd(mlo, 10, 0); - mhi = multadd(mhi, 10, 0); - } - } - } - else - for(i = 1;; i++) { - *s++ = dig = quorem(b,S) + '0'; - if (!b->x[0] && b->wds <= 1) { +keep_dig: +#endif + *s++ = dig; + if (i == ilim) { + break; + } + b = multadd(b, 10, 0); + if (mlo == mhi) { + mlo = mhi = multadd(mhi, 10, 0); + } + else { + mlo = multadd(mlo, 10, 0); + mhi = multadd(mhi, 10, 0); + } + } +} +else + for(i = 1;; i++) { + *s++ = dig = quorem(b,S) + '0'; + if (!b->x[0] && b->wds <= 1) { #ifdef SET_INEXACT - inexact = 0; + inexact = 0; #endif - goto ret; - } - if (i >= ilim) - break; - b = multadd(b, 10, 0); - } + goto ret; + } + if (i >= ilim) { + break; + } + b = multadd(b, 10, 0); + } - /* Round off last digit */ +/* Round off last digit */ #ifdef Honor_FLT_ROUNDS - switch(rounding) { - case 0: goto trimzeros; - case 2: goto roundoff; - } -#endif - b = lshift(b, 1); - j = cmp(b, S); - if (j > 0 || j == 0 && dig & 1) { - roundoff: - while(*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } - else { +switch(rounding) { +case 0: goto trimzeros; +case 2: goto roundoff; +} +#endif +b = lshift(b, 1); +j = cmp(b, S); +if (j > 0 || j == 0 && dig & 1) { +roundoff: + while(*--s == '9') + if (s == s0) { + k++; + *s++ = '1'; + goto ret; + } + ++*s++; +} +else { #ifdef Honor_FLT_ROUNDS - trimzeros: -#endif - while(*--s == '0'); - s++; - } - ret: - Bfree(S); - if (mhi) { - if (mlo && mlo != mhi) - Bfree(mlo); - Bfree(mhi); - } - ret1: +trimzeros: +#endif + while(*--s == '0'); + s++; +} +ret: +Bfree(S); +if (mhi) { + if (mlo && mlo != mhi) { + Bfree(mlo); + } + Bfree(mhi); +} +ret1: #ifdef SET_INEXACT - if (inexact) { - if (!oldinexact) { - word0(d) = Exp_1 + (70 << Exp_shift); - word1(d) = 0; - dval(d) += 1.; - } - } - else if (!oldinexact) - clear_inexact(); -#endif - Bfree(b); - *s = 0; - *decpt = k + 1; - if (rve) - *rve = s; - return s0; - } +if (inexact) { + if (!oldinexact) { + word0(d) = Exp_1 + (70 << Exp_shift); + word1(d) = 0; + dval(d) += 1.; + } +} +else if (!oldinexact) { + clear_inexact(); +} +#endif +Bfree(b); +*s = 0; +*decpt = k + 1; +if (rve) { + *rve = s; +} +return s0; +} #ifdef __cplusplus } #endif PR_IMPLEMENT(PRStatus) PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, - PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize) + PRIntn *decpt, PRIntn *sign, char **rve, char *buf, PRSize bufsize) { char *result; PRSize resultlen; PRStatus rv = PR_FAILURE; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (mode < 0 || mode > 3) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); @@ -3424,7 +3610,7 @@ PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, rv = PR_SUCCESS; } freedtoa(result); - return rv; + return rv; } /* @@ -3432,7 +3618,7 @@ PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits, ** prcsn - number of digits of precision to generate floating ** point value. ** This should be reparameterized so that you can send in a -** prcn for the positive and negative ranges. For now, +** prcn for the positive and negative ranges. For now, ** conform to the ECMA JavaScript spec which says numbers ** less than 1e-6 are in scientific notation. ** Also, the ECMA spec says that there should always be a @@ -3456,7 +3642,7 @@ PR_cnvtf(char *buf, int bufsz, int prcsn, double dfval) } /* XXX Why use mode 1? */ if (PR_dtoa(dval(fval),1,prcsn,&decpt,&sign,&endnum,num,bufsz) - == PR_FAILURE) { + == PR_FAILURE) { buf[0] = '\0'; goto done; } diff --git a/nsprpub/pr/src/misc/prenv.c b/nsprpub/pr/src/misc/prenv.c index cc2e198b9..b057a1c89 100644 --- a/nsprpub/pr/src/misc/prenv.c +++ b/nsprpub/pr/src/misc/prenv.c @@ -50,7 +50,7 @@ static PRLock *_pr_envLock = NULL; void _PR_InitEnv(void) { - _PR_NEW_LOCK_ENV(); + _PR_NEW_LOCK_ENV(); } void _PR_CleanupEnv(void) @@ -62,7 +62,9 @@ PR_IMPLEMENT(char*) PR_GetEnv(const char *var) { char *ev; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } _PR_LOCK_ENV(); ev = _PR_MD_GET_ENV(var); @@ -73,28 +75,30 @@ PR_IMPLEMENT(char*) PR_GetEnv(const char *var) PR_IMPLEMENT(char*) PR_GetEnvSecure(const char *var) { #ifdef HAVE_SECURE_GETENV - char *ev; + char *ev; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } - _PR_LOCK_ENV(); - ev = secure_getenv(var); - _PR_UNLOCK_ENV(); + _PR_LOCK_ENV(); + ev = secure_getenv(var); + _PR_UNLOCK_ENV(); - return ev; + return ev; #else #ifdef XP_UNIX - /* - ** Fall back to checking uids and gids. This won't detect any other - ** privilege-granting mechanisms the platform may have. This also - ** can't detect the case where the process already called - ** setuid(geteuid()) and/or setgid(getegid()). - */ - if (getuid() != geteuid() || getgid() != getegid()) { - return NULL; - } + /* + ** Fall back to checking uids and gids. This won't detect any other + ** privilege-granting mechanisms the platform may have. This also + ** can't detect the case where the process already called + ** setuid(geteuid()) and/or setgid(getegid()). + */ + if (getuid() != geteuid() || getgid() != getegid()) { + return NULL; + } #endif /* XP_UNIX */ - return PR_GetEnv(var); + return PR_GetEnv(var); #endif /* HAVE_SECURE_GETENV */ } @@ -102,9 +106,13 @@ PR_IMPLEMENT(PRStatus) PR_SetEnv(const char *string) { PRIntn result; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } - if (!strchr(string, '=')) return(PR_FAILURE); + if (!strchr(string, '=')) { + return(PR_FAILURE); + } _PR_LOCK_ENV(); result = _PR_MD_PUT_ENV((char*)string); @@ -135,21 +143,21 @@ PR_IMPLEMENT(char **) PR_DuplicateEnvironment(void) len = strlen(*src) + 1; *dst = PR_Malloc(len); if (*dst == NULL) { - /* Allocation failed. Must clean up the half-copied env. */ - char **to_delete; - - for (to_delete = result; to_delete != dst; to_delete++) { - PR_Free(*to_delete); - } - PR_Free(result); - result = NULL; - goto out; + /* Allocation failed. Must clean up the half-copied env. */ + char **to_delete; + + for (to_delete = result; to_delete != dst; to_delete++) { + PR_Free(*to_delete); + } + PR_Free(result); + result = NULL; + goto out; } memcpy(*dst, *src, len); } *dst = NULL; } - out: +out: _PR_UNLOCK_ENV(); return result; } diff --git a/nsprpub/pr/src/misc/prerr.c b/nsprpub/pr/src/misc/prerr.c index bc78c8fbf..99cf39f8c 100644 --- a/nsprpub/pr/src/misc/prerr.c +++ b/nsprpub/pr/src/misc/prerr.c @@ -10,84 +10,84 @@ */ #include "prerror.h" static const struct PRErrorMessage text[] = { - {"PR_OUT_OF_MEMORY_ERROR", "Memory allocation attempt failed"}, - {"PR_BAD_DESCRIPTOR_ERROR", "Invalid file descriptor"}, - {"PR_WOULD_BLOCK_ERROR", "The operation would have blocked"}, - {"PR_ACCESS_FAULT_ERROR", "Invalid memory address argument"}, - {"PR_INVALID_METHOD_ERROR", "Invalid function for file type"}, - {"PR_ILLEGAL_ACCESS_ERROR", "Invalid memory address argument"}, - {"PR_UNKNOWN_ERROR", "Some unknown error has occurred"}, - {"PR_PENDING_INTERRUPT_ERROR", "Operation interrupted by another thread"}, - {"PR_NOT_IMPLEMENTED_ERROR", "function not implemented"}, - {"PR_IO_ERROR", "I/O function error"}, - {"PR_IO_TIMEOUT_ERROR", "I/O operation timed out"}, - {"PR_IO_PENDING_ERROR", "I/O operation on busy file descriptor"}, - {"PR_DIRECTORY_OPEN_ERROR", "The directory could not be opened"}, - {"PR_INVALID_ARGUMENT_ERROR", "Invalid function argument"}, - {"PR_ADDRESS_NOT_AVAILABLE_ERROR", "Network address not available (in use?)"}, - {"PR_ADDRESS_NOT_SUPPORTED_ERROR", "Network address type not supported"}, - {"PR_IS_CONNECTED_ERROR", "Already connected"}, - {"PR_BAD_ADDRESS_ERROR", "Network address is invalid"}, - {"PR_ADDRESS_IN_USE_ERROR", "Local Network address is in use"}, - {"PR_CONNECT_REFUSED_ERROR", "Connection refused by peer"}, - {"PR_NETWORK_UNREACHABLE_ERROR", "Network address is presently unreachable"}, - {"PR_CONNECT_TIMEOUT_ERROR", "Connection attempt timed out"}, - {"PR_NOT_CONNECTED_ERROR", "Network file descriptor is not connected"}, - {"PR_LOAD_LIBRARY_ERROR", "Failure to load dynamic library"}, - {"PR_UNLOAD_LIBRARY_ERROR", "Failure to unload dynamic library"}, - {"PR_FIND_SYMBOL_ERROR", "Symbol not found in any of the loaded dynamic libraries"}, - {"PR_INSUFFICIENT_RESOURCES_ERROR", "Insufficient system resources"}, - {"PR_DIRECTORY_LOOKUP_ERROR", "A directory lookup on a network address has failed"}, - {"PR_TPD_RANGE_ERROR", "Attempt to access a TPD key that is out of range"}, - {"PR_PROC_DESC_TABLE_FULL_ERROR", "Process open FD table is full"}, - {"PR_SYS_DESC_TABLE_FULL_ERROR", "System open FD table is full"}, - {"PR_NOT_SOCKET_ERROR", "Network operation attempted on non-network file descriptor"}, - {"PR_NOT_TCP_SOCKET_ERROR", "TCP-specific function attempted on a non-TCP file descriptor"}, - {"PR_SOCKET_ADDRESS_IS_BOUND_ERROR", "TCP file descriptor is already bound"}, - {"PR_NO_ACCESS_RIGHTS_ERROR", "Access Denied"}, - {"PR_OPERATION_NOT_SUPPORTED_ERROR", "The requested operation is not supported by the platform"}, - {"PR_PROTOCOL_NOT_SUPPORTED_ERROR", "The host operating system does not support the protocol requested"}, - {"PR_REMOTE_FILE_ERROR", "Access to the remote file has been severed"}, - {"PR_BUFFER_OVERFLOW_ERROR", "The value requested is too large to be stored in the data buffer provided"}, - {"PR_CONNECT_RESET_ERROR", "TCP connection reset by peer"}, - {"PR_RANGE_ERROR", "Unused"}, - {"PR_DEADLOCK_ERROR", "The operation would have deadlocked"}, - {"PR_FILE_IS_LOCKED_ERROR", "The file is already locked"}, - {"PR_FILE_TOO_BIG_ERROR", "Write would result in file larger than the system allows"}, - {"PR_NO_DEVICE_SPACE_ERROR", "The device for storing the file is full"}, - {"PR_PIPE_ERROR", "Unused"}, - {"PR_NO_SEEK_DEVICE_ERROR", "Unused"}, - {"PR_IS_DIRECTORY_ERROR", "Cannot perform a normal file operation on a directory"}, - {"PR_LOOP_ERROR", "Symbolic link loop"}, - {"PR_NAME_TOO_LONG_ERROR", "File name is too long"}, - {"PR_FILE_NOT_FOUND_ERROR", "File not found"}, - {"PR_NOT_DIRECTORY_ERROR", "Cannot perform directory operation on a normal file"}, - {"PR_READ_ONLY_FILESYSTEM_ERROR", "Cannot write to a read-only file system"}, - {"PR_DIRECTORY_NOT_EMPTY_ERROR", "Cannot delete a directory that is not empty"}, - {"PR_FILESYSTEM_MOUNTED_ERROR", "Cannot delete or rename a file object while the file system is busy"}, - {"PR_NOT_SAME_DEVICE_ERROR", "Cannot rename a file to a file system on another device"}, - {"PR_DIRECTORY_CORRUPTED_ERROR", "The directory object in the file system is corrupted"}, - {"PR_FILE_EXISTS_ERROR", "Cannot create or rename a filename that already exists"}, - {"PR_MAX_DIRECTORY_ENTRIES_ERROR", "Directory is full. No additional filenames may be added"}, - {"PR_INVALID_DEVICE_STATE_ERROR", "The required device was in an invalid state"}, - {"PR_DEVICE_IS_LOCKED_ERROR", "The device is locked"}, - {"PR_NO_MORE_FILES_ERROR", "No more entries in the directory"}, - {"PR_END_OF_FILE_ERROR", "Encountered end of file"}, - {"PR_FILE_SEEK_ERROR", "Seek error"}, - {"PR_FILE_IS_BUSY_ERROR", "The file is busy"}, - {"PR_OPERATION_ABORTED_ERROR", "The I/O operation was aborted"}, - {"PR_IN_PROGRESS_ERROR", "Operation is still in progress (probably a non-blocking connect)"}, - {"PR_ALREADY_INITIATED_ERROR", "Operation has already been initiated (probably a non-blocking connect)"}, - {"PR_GROUP_EMPTY_ERROR", "The wait group is empty"}, - {"PR_INVALID_STATE_ERROR", "Object state improper for request"}, - {"PR_NETWORK_DOWN_ERROR", "Network is down"}, - {"PR_SOCKET_SHUTDOWN_ERROR", "Socket shutdown"}, - {"PR_CONNECT_ABORTED_ERROR", "Connection aborted"}, - {"PR_HOST_UNREACHABLE_ERROR", "Host is unreachable"}, - {"PR_LIBRARY_NOT_LOADED_ERROR", "The library is not loaded"}, - {"PR_CALL_ONCE_ERROR", "The one-time function was previously called and failed. Its error code is no longer available"}, - {"PR_MAX_ERROR", "Placeholder for the end of the list"}, - {0, 0} + {"PR_OUT_OF_MEMORY_ERROR", "Memory allocation attempt failed"}, + {"PR_BAD_DESCRIPTOR_ERROR", "Invalid file descriptor"}, + {"PR_WOULD_BLOCK_ERROR", "The operation would have blocked"}, + {"PR_ACCESS_FAULT_ERROR", "Invalid memory address argument"}, + {"PR_INVALID_METHOD_ERROR", "Invalid function for file type"}, + {"PR_ILLEGAL_ACCESS_ERROR", "Invalid memory address argument"}, + {"PR_UNKNOWN_ERROR", "Some unknown error has occurred"}, + {"PR_PENDING_INTERRUPT_ERROR", "Operation interrupted by another thread"}, + {"PR_NOT_IMPLEMENTED_ERROR", "function not implemented"}, + {"PR_IO_ERROR", "I/O function error"}, + {"PR_IO_TIMEOUT_ERROR", "I/O operation timed out"}, + {"PR_IO_PENDING_ERROR", "I/O operation on busy file descriptor"}, + {"PR_DIRECTORY_OPEN_ERROR", "The directory could not be opened"}, + {"PR_INVALID_ARGUMENT_ERROR", "Invalid function argument"}, + {"PR_ADDRESS_NOT_AVAILABLE_ERROR", "Network address not available (in use?)"}, + {"PR_ADDRESS_NOT_SUPPORTED_ERROR", "Network address type not supported"}, + {"PR_IS_CONNECTED_ERROR", "Already connected"}, + {"PR_BAD_ADDRESS_ERROR", "Network address is invalid"}, + {"PR_ADDRESS_IN_USE_ERROR", "Local Network address is in use"}, + {"PR_CONNECT_REFUSED_ERROR", "Connection refused by peer"}, + {"PR_NETWORK_UNREACHABLE_ERROR", "Network address is presently unreachable"}, + {"PR_CONNECT_TIMEOUT_ERROR", "Connection attempt timed out"}, + {"PR_NOT_CONNECTED_ERROR", "Network file descriptor is not connected"}, + {"PR_LOAD_LIBRARY_ERROR", "Failure to load dynamic library"}, + {"PR_UNLOAD_LIBRARY_ERROR", "Failure to unload dynamic library"}, + {"PR_FIND_SYMBOL_ERROR", "Symbol not found in any of the loaded dynamic libraries"}, + {"PR_INSUFFICIENT_RESOURCES_ERROR", "Insufficient system resources"}, + {"PR_DIRECTORY_LOOKUP_ERROR", "A directory lookup on a network address has failed"}, + {"PR_TPD_RANGE_ERROR", "Attempt to access a TPD key that is out of range"}, + {"PR_PROC_DESC_TABLE_FULL_ERROR", "Process open FD table is full"}, + {"PR_SYS_DESC_TABLE_FULL_ERROR", "System open FD table is full"}, + {"PR_NOT_SOCKET_ERROR", "Network operation attempted on non-network file descriptor"}, + {"PR_NOT_TCP_SOCKET_ERROR", "TCP-specific function attempted on a non-TCP file descriptor"}, + {"PR_SOCKET_ADDRESS_IS_BOUND_ERROR", "TCP file descriptor is already bound"}, + {"PR_NO_ACCESS_RIGHTS_ERROR", "Access Denied"}, + {"PR_OPERATION_NOT_SUPPORTED_ERROR", "The requested operation is not supported by the platform"}, + {"PR_PROTOCOL_NOT_SUPPORTED_ERROR", "The host operating system does not support the protocol requested"}, + {"PR_REMOTE_FILE_ERROR", "Access to the remote file has been severed"}, + {"PR_BUFFER_OVERFLOW_ERROR", "The value requested is too large to be stored in the data buffer provided"}, + {"PR_CONNECT_RESET_ERROR", "TCP connection reset by peer"}, + {"PR_RANGE_ERROR", "Unused"}, + {"PR_DEADLOCK_ERROR", "The operation would have deadlocked"}, + {"PR_FILE_IS_LOCKED_ERROR", "The file is already locked"}, + {"PR_FILE_TOO_BIG_ERROR", "Write would result in file larger than the system allows"}, + {"PR_NO_DEVICE_SPACE_ERROR", "The device for storing the file is full"}, + {"PR_PIPE_ERROR", "Unused"}, + {"PR_NO_SEEK_DEVICE_ERROR", "Unused"}, + {"PR_IS_DIRECTORY_ERROR", "Cannot perform a normal file operation on a directory"}, + {"PR_LOOP_ERROR", "Symbolic link loop"}, + {"PR_NAME_TOO_LONG_ERROR", "File name is too long"}, + {"PR_FILE_NOT_FOUND_ERROR", "File not found"}, + {"PR_NOT_DIRECTORY_ERROR", "Cannot perform directory operation on a normal file"}, + {"PR_READ_ONLY_FILESYSTEM_ERROR", "Cannot write to a read-only file system"}, + {"PR_DIRECTORY_NOT_EMPTY_ERROR", "Cannot delete a directory that is not empty"}, + {"PR_FILESYSTEM_MOUNTED_ERROR", "Cannot delete or rename a file object while the file system is busy"}, + {"PR_NOT_SAME_DEVICE_ERROR", "Cannot rename a file to a file system on another device"}, + {"PR_DIRECTORY_CORRUPTED_ERROR", "The directory object in the file system is corrupted"}, + {"PR_FILE_EXISTS_ERROR", "Cannot create or rename a filename that already exists"}, + {"PR_MAX_DIRECTORY_ENTRIES_ERROR", "Directory is full. No additional filenames may be added"}, + {"PR_INVALID_DEVICE_STATE_ERROR", "The required device was in an invalid state"}, + {"PR_DEVICE_IS_LOCKED_ERROR", "The device is locked"}, + {"PR_NO_MORE_FILES_ERROR", "No more entries in the directory"}, + {"PR_END_OF_FILE_ERROR", "Encountered end of file"}, + {"PR_FILE_SEEK_ERROR", "Seek error"}, + {"PR_FILE_IS_BUSY_ERROR", "The file is busy"}, + {"PR_OPERATION_ABORTED_ERROR", "The I/O operation was aborted"}, + {"PR_IN_PROGRESS_ERROR", "Operation is still in progress (probably a non-blocking connect)"}, + {"PR_ALREADY_INITIATED_ERROR", "Operation has already been initiated (probably a non-blocking connect)"}, + {"PR_GROUP_EMPTY_ERROR", "The wait group is empty"}, + {"PR_INVALID_STATE_ERROR", "Object state improper for request"}, + {"PR_NETWORK_DOWN_ERROR", "Network is down"}, + {"PR_SOCKET_SHUTDOWN_ERROR", "Socket shutdown"}, + {"PR_CONNECT_ABORTED_ERROR", "Connection aborted"}, + {"PR_HOST_UNREACHABLE_ERROR", "Host is unreachable"}, + {"PR_LIBRARY_NOT_LOADED_ERROR", "The library is not loaded"}, + {"PR_CALL_ONCE_ERROR", "The one-time function was previously called and failed. Its error code is no longer available"}, + {"PR_MAX_ERROR", "Placeholder for the end of the list"}, + {0, 0} }; static const struct PRErrorTable et = { text, "prerr", -6000L, 77 }; diff --git a/nsprpub/pr/src/misc/prerror.c b/nsprpub/pr/src/misc/prerror.c index 19f7794b4..a06b78ddb 100644 --- a/nsprpub/pr/src/misc/prerror.c +++ b/nsprpub/pr/src/misc/prerror.c @@ -34,25 +34,27 @@ PR_IMPLEMENT(void) PR_SetErrorText(PRIntn textLength, const char *text) if (0 == textLength) { - if (NULL != thread->errorString) - PR_DELETE(thread->errorString); - thread->errorStringSize = 0; + if (NULL != thread->errorString) { + PR_DELETE(thread->errorString); + } + thread->errorStringSize = 0; } else { - PRIntn size = textLength + 31; /* actual length to allocate. Plus a little extra */ + PRIntn size = textLength + 31; /* actual length to allocate. Plus a little extra */ if (thread->errorStringSize < textLength+1) /* do we have room? */ { - if (NULL != thread->errorString) - PR_DELETE(thread->errorString); - thread->errorString = (char*)PR_MALLOC(size); + if (NULL != thread->errorString) { + PR_DELETE(thread->errorString); + } + thread->errorString = (char*)PR_MALLOC(size); if ( NULL == thread->errorString ) { thread->errorStringSize = 0; thread->errorStringLength = 0; return; } thread->errorStringSize = size; - } + } memcpy(thread->errorString, text, textLength+1 ); } thread->errorStringLength = textLength; @@ -67,8 +69,9 @@ PR_IMPLEMENT(PRInt32) PR_GetErrorTextLength(void) PR_IMPLEMENT(PRInt32) PR_GetErrorText(char *text) { PRThread *thread = PR_GetCurrentThread(); - if (0 != thread->errorStringLength) + if (0 != thread->errorStringLength) { memcpy(text, thread->errorString, thread->errorStringLength+1); + } return thread->errorStringLength; } /* PR_GetErrorText */ diff --git a/nsprpub/pr/src/misc/prerrortable.c b/nsprpub/pr/src/misc/prerrortable.c index 285fde977..a7ff4f0eb 100644 --- a/nsprpub/pr/src/misc/prerrortable.c +++ b/nsprpub/pr/src/misc/prerrortable.c @@ -8,7 +8,7 @@ /* Copyright 1987, 1988 by the Student Information Processing Board - of the Massachusetts Institute of Technology + of the Massachusetts Institute of Technology Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is @@ -30,8 +30,8 @@ provided "as is" without express or implied warranty. #include "prmem.h" #include "prerror.h" -#define ERRCODE_RANGE 8 /* # of bits to shift table number */ -#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ +#define ERRCODE_RANGE 8 /* # of bits to shift table number */ +#define BITS_PER_CHAR 6 /* # bits to shift per character in name */ #ifdef NEED_SYS_ERRLIST extern char const * const sys_errlist[]; @@ -57,12 +57,12 @@ static PRErrorCallbackNewTableFn *callback_newtable = 0; static const char char_set[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"; static const char * error_table_name (PRErrorCode num) { - static char buf[6]; /* only used if internal code problems exist */ + static char buf[6]; /* only used if internal code problems exist */ long ch; int i; @@ -75,9 +75,10 @@ error_table_name (PRErrorCode num) num &= 077777777; /* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */ for (i = 4; i >= 0; i--) { - ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); - if (ch != 0) - *p++ = char_set[ch-1]; + ch = (num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1); + if (ch != 0) { + *p++ = char_set[ch-1]; + } } *p = '\0'; return(buf); @@ -99,40 +100,42 @@ PR_ErrorToString(PRErrorCode code, PRLanguageCode language) char *cp; for (et = Table_List; et; et = et->next) { - if (et->table->base <= code && - et->table->base + et->table->n_msgs > code) { - /* This is the right table */ - if (callback_lookup) { - msg = callback_lookup(code, language, et->table, - callback_private, et->table_private); - if (msg) return msg; - } - - return(et->table->msgs[code - et->table->base].en_text); - } + if (et->table->base <= code && + et->table->base + et->table->n_msgs > code) { + /* This is the right table */ + if (callback_lookup) { + msg = callback_lookup(code, language, et->table, + callback_private, et->table_private); + if (msg) { + return msg; + } + } + + return(et->table->msgs[code - et->table->base].en_text); + } } if (code >= 0 && code < 256) { - return strerror(code); + return strerror(code); } offset = (int) (code & ((1<<ERRCODE_RANGE)-1)); table_num = code - offset; strcpy (buffer, "Unknown code "); if (table_num) { - strcat(buffer, error_table_name (table_num)); - strcat(buffer, " "); + strcat(buffer, error_table_name (table_num)); + strcat(buffer, " "); } for (cp = buffer; *cp; cp++) - ; + ; if (offset >= 100) { - *cp++ = (char)('0' + offset / 100); - offset %= 100; - started++; + *cp++ = (char)('0' + offset / 100); + offset %= 100; + started++; } if (started || offset >= 10) { - *cp++ = (char)('0' + offset / 10); - offset %= 10; + *cp++ = (char)('0' + offset / 10); + offset %= 10; } *cp++ = (char)('0' + offset); *cp = '\0'; @@ -145,11 +148,11 @@ PR_ErrorToName(PRErrorCode code) struct PRErrorTableList *et; for (et = Table_List; et; et = et->next) { - if (et->table->base <= code && - et->table->base + et->table->n_msgs > code) { - /* This is the right table */ - return(et->table->msgs[code - et->table->base].name); - } + if (et->table->base <= code && + et->table->base + et->table->n_msgs > code) { + /* This is the right table */ + return(et->table->msgs[code - et->table->base].name); + } } return 0; @@ -167,14 +170,15 @@ PR_ErrorInstallTable(const struct PRErrorTable *table) struct PRErrorTableList * new_et; new_et = (struct PRErrorTableList *) - PR_Malloc(sizeof(struct PRErrorTableList)); - if (!new_et) - return errno; /* oops */ + PR_Malloc(sizeof(struct PRErrorTableList)); + if (!new_et) { + return errno; /* oops */ + } new_et->table = table; if (callback_newtable) { - new_et->table_private = callback_newtable(table, callback_private); + new_et->table_private = callback_newtable(table, callback_private); } else { - new_et->table_private = 0; + new_et->table_private = 0; } new_et->next = Table_List; Table_List = new_et; @@ -183,23 +187,23 @@ PR_ErrorInstallTable(const struct PRErrorTable *table) PR_IMPLEMENT(void) PR_ErrorInstallCallback(const char * const * languages, - PRErrorCallbackLookupFn *lookup, - PRErrorCallbackNewTableFn *newtable, - struct PRErrorCallbackPrivate *cb_private) + PRErrorCallbackLookupFn *lookup, + PRErrorCallbackNewTableFn *newtable, + struct PRErrorCallbackPrivate *cb_private) { struct PRErrorTableList *et; assert(strcmp(languages[0], "i-default") == 0); assert(strcmp(languages[1], "en") == 0); - + callback_languages = languages; callback_lookup = lookup; callback_newtable = newtable; callback_private = cb_private; if (callback_newtable) { - for (et = Table_List; et; et = et->next) { - et->table_private = callback_newtable(et->table, callback_private); - } + for (et = Table_List; et; et = et->next) { + et->table_private = callback_newtable(et->table, callback_private); + } } } diff --git a/nsprpub/pr/src/misc/prinit.c b/nsprpub/pr/src/misc/prinit.c index 43048a0d2..5ac99fe58 100644 --- a/nsprpub/pr/src/misc/prinit.c +++ b/nsprpub/pr/src/misc/prinit.c @@ -26,9 +26,9 @@ PRFileDesc *_pr_stderr; #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) PRCList _pr_active_local_threadQ = - PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ); + PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ); PRCList _pr_active_global_threadQ = - PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ); + PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ); _MDLock _pr_cpuLock; /* lock for the CPU Q */ PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ); @@ -41,10 +41,10 @@ PRUintn _pr_maxPTDs; #ifdef _PR_LOCAL_THREADS_ONLY -struct _PRCPU *_pr_currentCPU; -PRThread *_pr_currentThread; -PRThread *_pr_lastThread; -PRInt32 _pr_intsOff; +struct _PRCPU *_pr_currentCPU; +PRThread *_pr_currentThread; +PRThread *_pr_lastThread; +PRInt32 _pr_intsOff; #endif /* _PR_LOCAL_THREADS_ONLY */ @@ -138,7 +138,9 @@ static void _pr_SetNativeThreadsOnlyMode(void) static void _PR_InitStuff(void) { - if (_pr_initialized) return; + if (_pr_initialized) { + return; + } _pr_initialized = PR_TRUE; #ifdef _PR_ZONE_ALLOCATOR _PR_InitZones(); @@ -150,26 +152,26 @@ static void _PR_InitStuff(void) (void) PR_GetPageSize(); - _pr_clock_lm = PR_NewLogModule("clock"); - _pr_cmon_lm = PR_NewLogModule("cmon"); - _pr_io_lm = PR_NewLogModule("io"); - _pr_mon_lm = PR_NewLogModule("mon"); - _pr_linker_lm = PR_NewLogModule("linker"); - _pr_cvar_lm = PR_NewLogModule("cvar"); - _pr_sched_lm = PR_NewLogModule("sched"); - _pr_thread_lm = PR_NewLogModule("thread"); - _pr_gc_lm = PR_NewLogModule("gc"); - _pr_shm_lm = PR_NewLogModule("shm"); - _pr_shma_lm = PR_NewLogModule("shma"); - - /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ + _pr_clock_lm = PR_NewLogModule("clock"); + _pr_cmon_lm = PR_NewLogModule("cmon"); + _pr_io_lm = PR_NewLogModule("io"); + _pr_mon_lm = PR_NewLogModule("mon"); + _pr_linker_lm = PR_NewLogModule("linker"); + _pr_cvar_lm = PR_NewLogModule("cvar"); + _pr_sched_lm = PR_NewLogModule("sched"); + _pr_thread_lm = PR_NewLogModule("thread"); + _pr_gc_lm = PR_NewLogModule("gc"); + _pr_shm_lm = PR_NewLogModule("shm"); + _pr_shma_lm = PR_NewLogModule("shma"); + + /* NOTE: These init's cannot depend on _PR_MD_CURRENT_THREAD() */ _PR_MD_EARLY_INIT(); _PR_InitLocks(); _PR_InitAtomic(); _PR_InitSegs(); _PR_InitStacks(); - _PR_InitTPD(); + _PR_InitTPD(); _PR_InitEnv(); _PR_InitLayerCache(); _PR_InitClock(); @@ -178,22 +180,22 @@ static void _PR_InitStuff(void) PR_ASSERT(NULL != _pr_sleeplock); _PR_InitThreads(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); - + #ifdef WIN16 - { - PRInt32 top; /* artificial top of stack, win16 */ - _pr_top_of_task_stack = (char *) ⊤ - } -#endif + { + PRInt32 top; /* artificial top of stack, win16 */ + _pr_top_of_task_stack = (char *) ⊤ + } +#endif #ifndef _PR_GLOBAL_THREADS_ONLY - _PR_InitCPUs(); + _PR_InitCPUs(); #endif -/* - * XXX: call _PR_InitMem only on those platforms for which nspr implements - * malloc, for now. - */ + /* + * XXX: call _PR_InitMem only on those platforms for which nspr implements + * malloc, for now. + */ #ifdef _PR_OVERRIDE_MALLOC _PR_InitMem(); #endif @@ -216,7 +218,7 @@ static void _PR_InitStuff(void) void _PR_ImplicitInitialization(void) { - _PR_InitStuff(); + _PR_InitStuff(); /* Enable interrupts */ #if !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) @@ -228,20 +230,20 @@ void _PR_ImplicitInitialization(void) PR_IMPLEMENT(void) PR_DisableClockInterrupts(void) { #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - if (!_pr_initialized) { - _PR_InitStuff(); - } else { - _PR_MD_DISABLE_CLOCK_INTERRUPTS(); - } + if (!_pr_initialized) { + _PR_InitStuff(); + } else { + _PR_MD_DISABLE_CLOCK_INTERRUPTS(); + } #endif } PR_IMPLEMENT(void) PR_EnableClockInterrupts(void) { #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - if (!_pr_initialized) { - _PR_InitStuff(); - } + if (!_pr_initialized) { + _PR_InitStuff(); + } _PR_MD_ENABLE_CLOCK_INTERRUPTS(); #endif } @@ -249,14 +251,14 @@ PR_IMPLEMENT(void) PR_EnableClockInterrupts(void) PR_IMPLEMENT(void) PR_BlockClockInterrupts(void) { #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - _PR_MD_BLOCK_CLOCK_INTERRUPTS(); + _PR_MD_BLOCK_CLOCK_INTERRUPTS(); #endif } PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void) { #if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS) - _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(); + _PR_MD_UNBLOCK_CLOCK_INTERRUPTS(); #endif } @@ -272,7 +274,7 @@ PR_IMPLEMENT(PRIntn) PR_Initialize( PRIntn rv; _PR_ImplicitInitialization(); rv = prmain(argc, argv); - PR_Cleanup(); + PR_Cleanup(); return rv; } /* PR_Initialize */ @@ -281,7 +283,7 @@ PR_IMPLEMENT(PRIntn) PR_Initialize( * * _PR_CleanupBeforeExit -- * - * Perform the cleanup work before exiting the process. + * Perform the cleanup work before exiting the process. * We first do the cleanup generic to all platforms. Then * we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent * cleanup is done. This function is used by PR_Cleanup(). @@ -291,23 +293,25 @@ PR_IMPLEMENT(PRIntn) PR_Initialize( *----------------------------------------------------------------------- */ #if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) - /* see ptthread.c */ +/* see ptthread.c */ #else static void _PR_CleanupBeforeExit(void) { -/* -Do not make any calls here other than to destroy resources. For example, -do not make any calls that eventually may end up in PR_Lock. Because the -thread is destroyed, can not access current thread any more. -*/ + /* + Do not make any calls here other than to destroy resources. For example, + do not make any calls that eventually may end up in PR_Lock. Because the + thread is destroyed, can not access current thread any more. + */ _PR_CleanupTPD(); if (_pr_terminationCVLock) - /* - * In light of the comment above, this looks real suspicious. - * I'd go so far as to say it's just a problem waiting to happen. - */ + /* + * In light of the comment above, this looks real suspicious. + * I'd go so far as to say it's just a problem waiting to happen. + */ + { PR_DestroyLock(_pr_terminationCVLock); + } _PR_MD_CLEANUP_BEFORE_EXIT(); } @@ -329,7 +333,7 @@ thread is destroyed, can not access current thread any more. * Then it performs cleanup in preparation for exiting the process. * PR_Cleanup() does not exit the primordial thread (which would * in turn exit the process). - * + * * PR_Cleanup() only responds when it is called by the primordial * thread. Calls by any other thread are silently ignored. * @@ -338,7 +342,7 @@ thread is destroyed, can not access current thread any more. *---------------------------------------------------------------------- */ #if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) - /* see ptthread.c */ +/* see ptthread.c */ #else PR_IMPLEMENT(PRStatus) PR_Cleanup() @@ -369,21 +373,13 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup() } PR_Unlock(_pr_activeLock); -#ifdef IRIX - _PR_MD_PRE_CLEANUP(me); - /* - * The primordial thread must now be running on the primordial cpu - */ - PR_ASSERT((_PR_IS_NATIVE_THREAD(me)) || (me->cpu->id == 0)); -#endif - _PR_MD_EARLY_CLEANUP(); _PR_CleanupMW(); _PR_CleanupTime(); _PR_CleanupDtoa(); _PR_CleanupCallOnce(); - _PR_ShutdownLinker(); + _PR_ShutdownLinker(); _PR_CleanupNet(); _PR_CleanupIO(); /* Release the primordial thread's private data, etc. */ @@ -391,9 +387,9 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup() _PR_MD_STOP_INTERRUPTS(); - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_Cleanup: clean up before destroying thread")); - _PR_LogCleanup(); + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_Cleanup: clean up before destroying thread")); + _PR_LogCleanup(); /* * This part should look like the end of _PR_NativeRunThread @@ -436,18 +432,18 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup() /* *------------------------------------------------------------------------ * PR_ProcessExit -- - * + * * Cause an immediate, nongraceful, forced termination of the process. * It takes a PRIntn argument, which is the exit status code of the * process. - * + * * See also: PR_Cleanup() * *------------------------------------------------------------------------ */ #if defined(_PR_PTHREADS) || defined(_PR_BTHREADS) - /* see ptthread.c */ +/* see ptthread.c */ #else PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status) { @@ -518,7 +514,7 @@ PR_SetStdioRedirect( static PRBool warn = PR_TRUE; if (warn) { warn = _PR_Obsolete("PR_SetStdioRedirect()", - "PR_ProcessAttrSetStdioRedirect()"); + "PR_ProcessAttrSetStdioRedirect()"); } #endif PR_ProcessAttrSetStdioRedirect(attr, stdioFd, redirectFd); @@ -583,11 +579,11 @@ PR_ProcessAttrSetInheritableFD( if (NULL == attr->fdInheritBuffer) { /* The first time, we print "NSPR_INHERIT_FDS=<name>:<type>:<val>" */ newSize = NSPR_INHERIT_FDS_STRLEN + strlen(name) - + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1; + + FD_TYPE_STRLEN + OSFD_STRLEN + 2 + 1; } else { /* At other times, we print ":<name>:<type>:<val>" */ newSize = attr->fdInheritBufferUsed + strlen(name) - + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 1; + + FD_TYPE_STRLEN + OSFD_STRLEN + 3 + 1; } if (newSize > attr->fdInheritBufferSize) { /* Make newSize a multiple of FD_INHERIT_BUFFER_INCR */ @@ -611,13 +607,13 @@ PR_ProcessAttrSetInheritableFD( freeSize = attr->fdInheritBufferSize - attr->fdInheritBufferUsed; if (0 == attr->fdInheritBufferUsed) { nwritten = PR_snprintf(cur, freeSize, - "NSPR_INHERIT_FDS=%s:%d:0x%" PR_PRIxOSFD, - name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); + "NSPR_INHERIT_FDS=%s:%d:0x%" PR_PRIxOSFD, + name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); } else { nwritten = PR_snprintf(cur, freeSize, ":%s:%d:0x%" PR_PRIxOSFD, - name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); + name, (PRIntn)fd->methods->file_type, fd->secret->md.osfd); } - attr->fdInheritBufferUsed += nwritten; + attr->fdInheritBufferUsed += nwritten; return PR_SUCCESS; } @@ -713,13 +709,13 @@ PR_IMPLEMENT(PRStatus) PR_CreateProcessDetached( process = PR_CreateProcess(path, argv, envp, attr); if (NULL == process) { - return PR_FAILURE; + return PR_FAILURE; } rv = PR_DetachProcess(process); PR_ASSERT(PR_SUCCESS == rv); if (rv == PR_FAILURE) { - PR_DELETE(process); - return PR_FAILURE; + PR_DELETE(process); + return PR_FAILURE; } return PR_SUCCESS; } @@ -771,22 +767,24 @@ PR_IMPLEMENT(PRStatus) PR_CallOnce( PRCallOnceType *once, PRCallOnceFN func) { - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (!once->initialized) { - if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { - once->status = (*func)(); - PR_Lock(mod_init.ml); - once->initialized = 1; - PR_NotifyAllCondVar(mod_init.cv); - PR_Unlock(mod_init.ml); - } else { - PR_Lock(mod_init.ml); - while (!once->initialized) { - PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); + if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { + once->status = (*func)(); + PR_Lock(mod_init.ml); + once->initialized = 1; + PR_NotifyAllCondVar(mod_init.cv); + PR_Unlock(mod_init.ml); + } else { + PR_Lock(mod_init.ml); + while (!once->initialized) { + PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); } - PR_Unlock(mod_init.ml); - } + PR_Unlock(mod_init.ml); + } } else { if (PR_SUCCESS != once->status) { PR_SetError(PR_CALL_ONCE_ERROR, 0); @@ -800,22 +798,24 @@ PR_IMPLEMENT(PRStatus) PR_CallOnceWithArg( PRCallOnceWithArgFN func, void *arg) { - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (!once->initialized) { - if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { - once->status = (*func)(arg); - PR_Lock(mod_init.ml); - once->initialized = 1; - PR_NotifyAllCondVar(mod_init.cv); - PR_Unlock(mod_init.ml); - } else { - PR_Lock(mod_init.ml); - while (!once->initialized) { - PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); + if (PR_ATOMIC_SET(&once->inProgress, 1) == 0) { + once->status = (*func)(arg); + PR_Lock(mod_init.ml); + once->initialized = 1; + PR_NotifyAllCondVar(mod_init.cv); + PR_Unlock(mod_init.ml); + } else { + PR_Lock(mod_init.ml); + while (!once->initialized) { + PR_WaitCondVar(mod_init.cv, PR_INTERVAL_NO_TIMEOUT); } - PR_Unlock(mod_init.ml); - } + PR_Unlock(mod_init.ml); + } } else { if (PR_SUCCESS != once->status) { PR_SetError(PR_CALL_ONCE_ERROR, 0); diff --git a/nsprpub/pr/src/misc/prinrval.c b/nsprpub/pr/src/misc/prinrval.c index 50a938b52..79ff2cbca 100644 --- a/nsprpub/pr/src/misc/prinrval.c +++ b/nsprpub/pr/src/misc/prinrval.c @@ -4,8 +4,8 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* - * file: prinrval.c - * description: implementation for the kernel interval timing functions + * file: prinrval.c + * description: implementation for the kernel interval timing functions */ #include "primpl.h" @@ -34,13 +34,17 @@ void _PR_InitClock(void) PR_IMPLEMENT(PRIntervalTime) PR_IntervalNow(void) { - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } return _PR_MD_GET_INTERVAL(); } /* PR_IntervalNow */ PR_EXTERN(PRUint32) PR_TicksPerSecond(void) { - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } return _PR_MD_INTERVAL_PER_SEC(); } /* PR_TicksPerSecond */ diff --git a/nsprpub/pr/src/misc/pripc.c b/nsprpub/pr/src/misc/pripc.c index e41a2afcf..64415dd63 100644 --- a/nsprpub/pr/src/misc/pripc.c +++ b/nsprpub/pr/src/misc/pripc.c @@ -17,7 +17,7 @@ * A POSIX IPC name must begin with a '/'. * A POSIX IPC name on Solaris cannot contain any '/' except * the required leading '/'. - * A POSIX IPC name on HP-UX and OSF1 must be a valid pathname + * A POSIX IPC name on HP-UX must be a valid pathname * in the file system. * * The ftok() function for System V IPC requires a valid pathname diff --git a/nsprpub/pr/src/misc/pripcsem.c b/nsprpub/pr/src/misc/pripcsem.c index a17689788..49b051b74 100644 --- a/nsprpub/pr/src/misc/pripcsem.c +++ b/nsprpub/pr/src/misc/pripcsem.c @@ -60,9 +60,11 @@ PR_IMPLEMENT(PRSem *) PR_OpenSemaphore( { char osname[PR_IPC_NAME_SIZE]; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) { + == PR_FAILURE) { return NULL; } return _PR_MD_OPEN_SEMAPHORE(osname, flags, mode, value); @@ -87,9 +89,11 @@ PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name) { char osname[PR_IPC_NAME_SIZE]; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (_PR_MakeNativeIPCName(name, osname, sizeof(osname), _PRIPCSem) - == PR_FAILURE) { + == PR_FAILURE) { return PR_FAILURE; } return _PR_MD_DELETE_SEMAPHORE(osname); diff --git a/nsprpub/pr/src/misc/prlong.c b/nsprpub/pr/src/misc/prlong.c index 185fa5cd4..9c5abf06b 100644 --- a/nsprpub/pr/src/misc/prlong.c +++ b/nsprpub/pr/src/misc/prlong.c @@ -10,10 +10,18 @@ static PRInt64 ll_maxint = PR_INT64(0x7fffffffffffffff); static PRInt64 ll_minint = PR_INT64(0x8000000000000000); static PRUint64 ll_maxuint = PR_UINT64(0xffffffffffffffff); -PR_IMPLEMENT(PRInt64) LL_Zero(void) { return ll_zero; } -PR_IMPLEMENT(PRInt64) LL_MaxInt(void) { return ll_maxint; } -PR_IMPLEMENT(PRInt64) LL_MinInt(void) { return ll_minint; } -PR_IMPLEMENT(PRUint64) LL_MaxUint(void) { return ll_maxuint; } +PR_IMPLEMENT(PRInt64) LL_Zero(void) { + return ll_zero; +} +PR_IMPLEMENT(PRInt64) LL_MaxInt(void) { + return ll_maxint; +} +PR_IMPLEMENT(PRInt64) LL_MinInt(void) { + return ll_minint; +} +PR_IMPLEMENT(PRUint64) LL_MaxUint(void) { + return ll_maxuint; +} #ifndef HAVE_LONG_LONG /* @@ -32,10 +40,10 @@ static void norm_udivmod32(PRUint32 *qp, PRUint32 *rp, PRUint64 a, PRUint32 b) r1 = (r1 << 16) | _hi16(a.lo); if (r1 < m) { q1--, r1 += b; - if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */ - && r1 < m) { - q1--, r1 += b; - } + if (r1 >= b /* i.e., we didn't get a carry when adding to r1 */ + && r1 < m) { + q1--, r1 += b; + } } r1 -= m; r0 = r1 % d1; @@ -45,9 +53,9 @@ static void norm_udivmod32(PRUint32 *qp, PRUint32 *rp, PRUint64 a, PRUint32 b) if (r0 < m) { q0--, r0 += b; if (r0 >= b - && r0 < m) { - q0--, r0 += b; - } + && r0 < m) { + q0--, r0 += b; + } } *qp = (q1 << 16) | q0; *rp = r0 - m; @@ -58,18 +66,24 @@ static PRUint32 CountLeadingZeros(PRUint32 a) PRUint32 t; PRUint32 r = 32; - if ((t = a >> 16) != 0) - r -= 16, a = t; - if ((t = a >> 8) != 0) - r -= 8, a = t; - if ((t = a >> 4) != 0) - r -= 4, a = t; - if ((t = a >> 2) != 0) - r -= 2, a = t; - if ((t = a >> 1) != 0) - r -= 1, a = t; - if (a & 1) - r--; + if ((t = a >> 16) != 0) { + r -= 16, a = t; + } + if ((t = a >> 8) != 0) { + r -= 8, a = t; + } + if ((t = a >> 4) != 0) { + r -= 4, a = t; + } + if ((t = a >> 2) != 0) { + r -= 2, a = t; + } + if ((t = a >> 1) != 0) { + r -= 1, a = t; + } + if (a & 1) { + r--; + } return r; } @@ -83,157 +97,158 @@ PR_IMPLEMENT(void) ll_udivmod(PRUint64 *qp, PRUint64 *rp, PRUint64 a, PRUint64 b n1 = a.hi; if (b.hi == 0) { - if (b.lo > n1) { - /* (0 q0) = (n1 n0) / (0 D0) */ - - lsh = CountLeadingZeros(b.lo); - - if (lsh) { - /* - * Normalize, i.e. make the most significant bit of the - * denominator be set. - */ - b.lo = b.lo << lsh; - n1 = (n1 << lsh) | (n0 >> (32 - lsh)); - n0 = n0 << lsh; - } - - a.lo = n0, a.hi = n1; - norm_udivmod32(&q0, &n0, a, b.lo); - q1 = 0; - - /* remainder is in n0 >> lsh */ - } else { - /* (q1 q0) = (n1 n0) / (0 d0) */ - - if (b.lo == 0) /* user wants to divide by zero! */ - b.lo = 1 / b.lo; /* so go ahead and crash */ - - lsh = CountLeadingZeros(b.lo); - - if (lsh == 0) { - /* - * From (n1 >= b.lo) - * && (the most significant bit of b.lo is set), - * conclude that - * (the most significant bit of n1 is set) - * && (the leading quotient digit q1 = 1). - * - * This special case is necessary, not an optimization - * (Shifts counts of 32 are undefined). - */ - n1 -= b.lo; - q1 = 1; - } else { - /* - * Normalize. - */ - rsh = 32 - lsh; - - b.lo = b.lo << lsh; - n2 = n1 >> rsh; - n1 = (n1 << lsh) | (n0 >> rsh); - n0 = n0 << lsh; - - a.lo = n1, a.hi = n2; - norm_udivmod32(&q1, &n1, a, b.lo); - } - - /* n1 != b.lo... */ - - a.lo = n0, a.hi = n1; - norm_udivmod32(&q0, &n0, a, b.lo); - - /* remainder in n0 >> lsh */ - } - - if (rp) { - rp->lo = n0 >> lsh; - rp->hi = 0; - } + if (b.lo > n1) { + /* (0 q0) = (n1 n0) / (0 D0) */ + + lsh = CountLeadingZeros(b.lo); + + if (lsh) { + /* + * Normalize, i.e. make the most significant bit of the + * denominator be set. + */ + b.lo = b.lo << lsh; + n1 = (n1 << lsh) | (n0 >> (32 - lsh)); + n0 = n0 << lsh; + } + + a.lo = n0, a.hi = n1; + norm_udivmod32(&q0, &n0, a, b.lo); + q1 = 0; + + /* remainder is in n0 >> lsh */ + } else { + /* (q1 q0) = (n1 n0) / (0 d0) */ + + if (b.lo == 0) { /* user wants to divide by zero! */ + b.lo = 1 / b.lo; /* so go ahead and crash */ + } + + lsh = CountLeadingZeros(b.lo); + + if (lsh == 0) { + /* + * From (n1 >= b.lo) + * && (the most significant bit of b.lo is set), + * conclude that + * (the most significant bit of n1 is set) + * && (the leading quotient digit q1 = 1). + * + * This special case is necessary, not an optimization + * (Shifts counts of 32 are undefined). + */ + n1 -= b.lo; + q1 = 1; + } else { + /* + * Normalize. + */ + rsh = 32 - lsh; + + b.lo = b.lo << lsh; + n2 = n1 >> rsh; + n1 = (n1 << lsh) | (n0 >> rsh); + n0 = n0 << lsh; + + a.lo = n1, a.hi = n2; + norm_udivmod32(&q1, &n1, a, b.lo); + } + + /* n1 != b.lo... */ + + a.lo = n0, a.hi = n1; + norm_udivmod32(&q0, &n0, a, b.lo); + + /* remainder in n0 >> lsh */ + } + + if (rp) { + rp->lo = n0 >> lsh; + rp->hi = 0; + } } else { - if (b.hi > n1) { - /* (0 0) = (n1 n0) / (D1 d0) */ - - q0 = 0; - q1 = 0; - - /* remainder in (n1 n0) */ - if (rp) { - rp->lo = n0; - rp->hi = n1; - } - } else { - /* (0 q0) = (n1 n0) / (d1 d0) */ - - lsh = CountLeadingZeros(b.hi); - if (lsh == 0) { - /* - * From (n1 >= b.hi) - * && (the most significant bit of b.hi is set), - * conclude that - * (the most significant bit of n1 is set) - * && (the quotient digit q0 = 0 or 1). - * - * This special case is necessary, not an optimization. - */ - - /* - * The condition on the next line takes advantage of that - * n1 >= b.hi (true due to control flow). - */ - if (n1 > b.hi || n0 >= b.lo) { - q0 = 1; - a.lo = n0, a.hi = n1; - LL_SUB(a, a, b); - } else { - q0 = 0; - } - q1 = 0; - - if (rp) { - rp->lo = n0; - rp->hi = n1; - } - } else { - PRInt64 m; - - /* - * Normalize. - */ - rsh = 32 - lsh; - - b.hi = (b.hi << lsh) | (b.lo >> rsh); - b.lo = b.lo << lsh; - n2 = n1 >> rsh; - n1 = (n1 << lsh) | (n0 >> rsh); - n0 = n0 << lsh; - - a.lo = n1, a.hi = n2; - norm_udivmod32(&q0, &n1, a, b.hi); - LL_MUL32(m, q0, b.lo); - - if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) { - q0--; - LL_SUB(m, m, b); - } - - q1 = 0; - - /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */ - if (rp) { - a.lo = n0, a.hi = n1; - LL_SUB(a, a, m); - rp->lo = (a.hi << rsh) | (a.lo >> lsh); - rp->hi = a.hi >> lsh; - } - } - } + if (b.hi > n1) { + /* (0 0) = (n1 n0) / (D1 d0) */ + + q0 = 0; + q1 = 0; + + /* remainder in (n1 n0) */ + if (rp) { + rp->lo = n0; + rp->hi = n1; + } + } else { + /* (0 q0) = (n1 n0) / (d1 d0) */ + + lsh = CountLeadingZeros(b.hi); + if (lsh == 0) { + /* + * From (n1 >= b.hi) + * && (the most significant bit of b.hi is set), + * conclude that + * (the most significant bit of n1 is set) + * && (the quotient digit q0 = 0 or 1). + * + * This special case is necessary, not an optimization. + */ + + /* + * The condition on the next line takes advantage of that + * n1 >= b.hi (true due to control flow). + */ + if (n1 > b.hi || n0 >= b.lo) { + q0 = 1; + a.lo = n0, a.hi = n1; + LL_SUB(a, a, b); + } else { + q0 = 0; + } + q1 = 0; + + if (rp) { + rp->lo = n0; + rp->hi = n1; + } + } else { + PRInt64 m; + + /* + * Normalize. + */ + rsh = 32 - lsh; + + b.hi = (b.hi << lsh) | (b.lo >> rsh); + b.lo = b.lo << lsh; + n2 = n1 >> rsh; + n1 = (n1 << lsh) | (n0 >> rsh); + n0 = n0 << lsh; + + a.lo = n1, a.hi = n2; + norm_udivmod32(&q0, &n1, a, b.hi); + LL_MUL32(m, q0, b.lo); + + if ((m.hi > n1) || ((m.hi == n1) && (m.lo > n0))) { + q0--; + LL_SUB(m, m, b); + } + + q1 = 0; + + /* Remainder is ((n1 n0) - (m1 m0)) >> lsh */ + if (rp) { + a.lo = n0, a.hi = n1; + LL_SUB(a, a, m); + rp->lo = (a.hi << rsh) | (a.lo >> lsh); + rp->hi = a.hi >> lsh; + } + } + } } if (qp) { - qp->lo = q0; - qp->hi = q1; + qp->lo = q0; + qp->hi = q1; } } #endif /* !HAVE_LONG_LONG */ diff --git a/nsprpub/pr/src/misc/prnetdb.c b/nsprpub/pr/src/misc/prnetdb.c index c482e8e4a..6ad0242d6 100644 --- a/nsprpub/pr/src/misc/prnetdb.c +++ b/nsprpub/pr/src/misc/prnetdb.c @@ -29,14 +29,13 @@ extern int h_errno; * The meaning of the macros related to gethostbyname, gethostbyaddr, * and gethostbyname2 is defined below. * - _PR_HAVE_THREADSAFE_GETHOST: the gethostbyXXX functions return - * the result in thread specific storage. For example, AIX, HP-UX, - * and OSF1. + * the result in thread specific storage. For example, AIX, HP-UX. * - _PR_HAVE_GETHOST_R: have the gethostbyXXX_r functions. See next * two macros. * - _PR_HAVE_GETHOST_R_INT: the gethostbyXXX_r functions return an * int. For example, Linux glibc. * - _PR_HAVE_GETHOST_R_POINTER: the gethostbyXXX_r functions return - * a struct hostent* pointer. For example, Solaris and IRIX. + * a struct hostent* pointer. For example, Solaris. */ #if defined(_PR_NO_PREEMPT) || defined(_PR_HAVE_GETHOST_R) \ || defined(_PR_HAVE_THREADSAFE_GETHOST) @@ -58,23 +57,16 @@ PRLock *_pr_dnsLock = NULL; * Some return a pointer to struct protoent, others return * an int, and glibc's flavor takes five arguments. */ -#if defined(XP_BEOS) && defined(BONE_VERSION) -#include <arpa/inet.h> /* pick up define for inet_addr */ -#include <sys/socket.h> -#define _PR_HAVE_GETPROTO_R -#define _PR_HAVE_GETPROTO_R_POINTER -#endif #if defined(SOLARIS) || (defined(BSDI) && defined(_REENTRANT)) \ - || (defined(LINUX) && defined(_REENTRANT) \ + || (defined(LINUX) && defined(_REENTRANT) \ && defined(__GLIBC__) && __GLIBC__ < 2) #define _PR_HAVE_GETPROTO_R #define _PR_HAVE_GETPROTO_R_POINTER #endif -#if defined(OSF1) \ - || defined(AIX4_3_PLUS) || (defined(AIX) && defined(_THREAD_SAFE)) \ - || (defined(HPUX10_10) && defined(_REENTRANT)) \ +#if defined(AIX4_3_PLUS) || (defined(AIX) && defined(_THREAD_SAFE)) \ + || (defined(HPUX10_10) && defined(_REENTRANT)) \ || (defined(HPUX10_20) && defined(_REENTRANT)) \ || defined(OPENBSD) #define _PR_HAVE_GETPROTO_R @@ -87,7 +79,7 @@ PRLock *_pr_dnsLock = NULL; #endif /* BeOS has glibc but not the glibc-style getprotobyxxx_r functions. */ -#if (defined(__GLIBC__) && __GLIBC__ >= 2 && !defined(XP_BEOS)) +#if (defined(__GLIBC__) && __GLIBC__ >= 2) #define _PR_HAVE_GETPROTO_R #define _PR_HAVE_5_ARG_GETPROTO_R #endif @@ -100,48 +92,56 @@ PRLock* _getproto_lock = NULL; extern PRBool _pr_ipv6_is_present(void); #endif -#define _PR_IN6_IS_ADDR_UNSPECIFIED(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr32[2] == 0) && \ - ((a)->pr_s6_addr32[3] == 0)) - -#define _PR_IN6_IS_ADDR_LOOPBACK(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr32[2] == 0) && \ - ((a)->pr_s6_addr[12] == 0) && \ - ((a)->pr_s6_addr[13] == 0) && \ - ((a)->pr_s6_addr[14] == 0) && \ +#define _PR_IN6_IS_ADDR_UNSPECIFIED(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr32[2] == 0) && \ + ((a)->pr_s6_addr32[3] == 0)) + +#define _PR_IN6_IS_ADDR_LOOPBACK(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr32[2] == 0) && \ + ((a)->pr_s6_addr[12] == 0) && \ + ((a)->pr_s6_addr[13] == 0) && \ + ((a)->pr_s6_addr[14] == 0) && \ ((a)->pr_s6_addr[15] == 0x1U)) - -const PRIPv6Addr _pr_in6addr_any = {{{ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0 }}}; - -const PRIPv6Addr _pr_in6addr_loopback = {{{ 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0x1U }}}; + +const PRIPv6Addr _pr_in6addr_any = {{{ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 + } + } +}; + +const PRIPv6Addr _pr_in6addr_loopback = {{{ + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0x1U + } + } +}; /* * The values at bytes 10 and 11 are compared using pointers to * 8-bit fields, and not 32-bit fields, to make the comparison work on * both big-endian and little-endian systems */ -#define _PR_IN6_IS_ADDR_V4MAPPED(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr[8] == 0) && \ - ((a)->pr_s6_addr[9] == 0) && \ - ((a)->pr_s6_addr[10] == 0xff) && \ - ((a)->pr_s6_addr[11] == 0xff)) +#define _PR_IN6_IS_ADDR_V4MAPPED(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr[8] == 0) && \ + ((a)->pr_s6_addr[9] == 0) && \ + ((a)->pr_s6_addr[10] == 0xff) && \ + ((a)->pr_s6_addr[11] == 0xff)) -#define _PR_IN6_IS_ADDR_V4COMPAT(a) \ - (((a)->pr_s6_addr32[0] == 0) && \ - ((a)->pr_s6_addr32[1] == 0) && \ - ((a)->pr_s6_addr32[2] == 0)) +#define _PR_IN6_IS_ADDR_V4COMPAT(a) \ + (((a)->pr_s6_addr32[0] == 0) && \ + ((a)->pr_s6_addr32[1] == 0) && \ + ((a)->pr_s6_addr32[2] == 0)) #define _PR_IN6_V4MAPPED_TO_IPADDR(a) ((a)->pr_s6_addr32[3]) @@ -247,8 +247,9 @@ _pr_QueryNetIfs(void) return; } } else { - if (ifc.ifc_len == lastlen) - break; /* success, len has not changed */ + if (ifc.ifc_len == lastlen) { + break; /* success, len has not changed */ + } lastlen = ifc.ifc_len; } len += 10 * sizeof(struct ifreq); /* increment */ @@ -271,13 +272,13 @@ _pr_QueryNetIfs(void) struct sockaddr_in *sin = (struct sockaddr_in *) sa; if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { _pr_have_inet_if = PR_TRUE; - } + } } else if (sa->sa_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) - && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { _pr_have_inet6_if = PR_TRUE; - } + } } #ifdef _PR_HAVE_SOCKADDR_LEN @@ -285,16 +286,16 @@ _pr_QueryNetIfs(void) #else switch (sa->sa_family) { #ifdef AF_LINK - case AF_LINK: - sa_len = sizeof(struct sockaddr_dl); - break; -#endif - case AF_INET6: - sa_len = sizeof(struct sockaddr_in6); - break; - default: - sa_len = sizeof(struct sockaddr); - break; + case AF_LINK: + sa_len = sizeof(struct sockaddr_dl); + break; +#endif + case AF_INET6: + sa_len = sizeof(struct sockaddr_in6); + break; + default: + sa_len = sizeof(struct sockaddr); + break; } #endif ifr = (struct ifreq *)(((char *)sa) + sa_len); @@ -360,15 +361,15 @@ _pr_QueryNetIfs(void) struct sockaddr_in *sin = (struct sockaddr_in *) sa; if (sin->sin_addr.s_addr != htonl(INADDR_LOOPBACK)) { _pr_have_inet_if = 1; - } + } } else if (sa->sa_family == AF_INET6) { struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa; if (!IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) - && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { + && !IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) { _pr_have_inet6_if = 1; - } + } } - } + } freeifaddrs(ifp); } @@ -393,21 +394,21 @@ void _PR_InitNet(void) { #if defined(XP_UNIX) #ifdef HAVE_NETCONFIG - /* - * This one-liner prevents the endless re-open's and re-read's of - * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc. - */ - (void)setnetconfig(); + /* + * This one-liner prevents the endless re-open's and re-read's of + * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc. + */ + (void)setnetconfig(); #endif #endif #if !defined(_PR_NO_DNS_LOCK) - _pr_dnsLock = PR_NewLock(); + _pr_dnsLock = PR_NewLock(); #endif #if !defined(_PR_HAVE_GETPROTO_R) - _getproto_lock = PR_NewLock(); + _getproto_lock = PR_NewLock(); #endif #if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - _pr_query_ifs_lock = PR_NewLock(); + _pr_query_ifs_lock = PR_NewLock(); #endif } @@ -439,23 +440,23 @@ void _PR_CleanupNet(void) */ static char *Alloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align) { - char *buf = *bufp; - PRIntn buflen = *buflenp; - - if (align && ((long)buf & (align - 1))) { - PRIntn skip = align - ((ptrdiff_t)buf & (align - 1)); - if (buflen < skip) { - return 0; - } - buf += skip; - buflen -= skip; - } - if (buflen < amount) { - return 0; - } - *bufp = buf + amount; - *buflenp = buflen - amount; - return buf; + char *buf = *bufp; + PRIntn buflen = *buflenp; + + if (align && ((long)buf & (align - 1))) { + PRIntn skip = align - ((ptrdiff_t)buf & (align - 1)); + if (buflen < skip) { + return 0; + } + buf += skip; + buflen -= skip; + } + if (buflen < amount) { + return 0; + } + *bufp = buf + amount; + *buflenp = buflen - amount; + return buf; } typedef enum _PRIPAddrConversion { @@ -494,98 +495,92 @@ static PRStatus CopyHostent( _PRIPAddrConversion conversion, PRHostEnt *to) { - PRIntn len, na; - char **ap; - - if (conversion != _PRIPAddrNoConversion - && from->h_addrtype == AF_INET) { - PR_ASSERT(from->h_length == 4); - to->h_addrtype = PR_AF_INET6; - to->h_length = 16; - } else { -#if defined(_PR_INET6) || defined(_PR_INET6_PROBE) - if (AF_INET6 == from->h_addrtype) - to->h_addrtype = PR_AF_INET6; - else -#endif - to->h_addrtype = from->h_addrtype; - to->h_length = from->h_length; - } - - /* Copy the official name */ - if (!from->h_name) return PR_FAILURE; - len = strlen(from->h_name) + 1; - to->h_name = Alloc(len, buf, bufsize, 0); - if (!to->h_name) return PR_FAILURE; - memcpy(to->h_name, from->h_name, len); - - /* Count the aliases, then allocate storage for the pointers */ - if (!from->h_aliases) { - na = 1; - } else { - for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */ - } - to->h_aliases = (char**)Alloc( - na * sizeof(char*), buf, bufsize, sizeof(char**)); - if (!to->h_aliases) return PR_FAILURE; - - /* Copy the aliases, one at a time */ - if (!from->h_aliases) { - to->h_aliases[0] = 0; - } else { - for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) { - len = strlen(*ap) + 1; - to->h_aliases[na] = Alloc(len, buf, bufsize, 0); - if (!to->h_aliases[na]) return PR_FAILURE; - memcpy(to->h_aliases[na], *ap, len); - } - to->h_aliases[na] = 0; - } - - /* Count the addresses, then allocate storage for the pointers */ - for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */ - to->h_addr_list = (char**)Alloc( - na * sizeof(char*), buf, bufsize, sizeof(char**)); - if (!to->h_addr_list) return PR_FAILURE; - - /* Copy the addresses, one at a time */ - for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) { - to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0); - if (!to->h_addr_list[na]) return PR_FAILURE; - if (conversion != _PRIPAddrNoConversion - && from->h_addrtype == AF_INET) { - if (conversion == _PRIPAddrIPv4Mapped) { - MakeIPv4MappedAddr(*ap, to->h_addr_list[na]); - } else { - PR_ASSERT(conversion == _PRIPAddrIPv4Compat); - MakeIPv4CompatAddr(*ap, to->h_addr_list[na]); - } - } else { - memcpy(to->h_addr_list[na], *ap, to->h_length); - } - } - to->h_addr_list[na] = 0; - return PR_SUCCESS; -} + PRIntn len, na; + char **ap; -#ifdef SYMBIAN -/* Set p_aliases by hand because Symbian's getprotobyname() returns NULL. */ -static void AssignAliases(struct protoent *Protoent, char** aliases) -{ - if (NULL == Protoent->p_aliases) { - if (0 == strcmp(Protoent->p_name, "ip")) - aliases[0] = "IP"; - else if (0 == strcmp(Protoent->p_name, "tcp")) - aliases[0] = "TCP"; - else if (0 == strcmp(Protoent->p_name, "udp")) - aliases[0] = "UDP"; + if (conversion != _PRIPAddrNoConversion + && from->h_addrtype == AF_INET) { + PR_ASSERT(from->h_length == 4); + to->h_addrtype = PR_AF_INET6; + to->h_length = 16; + } else { +#if defined(_PR_INET6) || defined(_PR_INET6_PROBE) + if (AF_INET6 == from->h_addrtype) { + to->h_addrtype = PR_AF_INET6; + } else - aliases[0] = "UNKNOWN"; - aliases[1] = NULL; - Protoent->p_aliases = aliases; +#endif + to->h_addrtype = from->h_addrtype; + to->h_length = from->h_length; } + + /* Copy the official name */ + if (!from->h_name) { + return PR_FAILURE; + } + len = strlen(from->h_name) + 1; + to->h_name = Alloc(len, buf, bufsize, 0); + if (!to->h_name) { + return PR_FAILURE; + } + memcpy(to->h_name, from->h_name, len); + + /* Count the aliases, then allocate storage for the pointers */ + if (!from->h_aliases) { + na = 1; + } else { + for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++) {;} /* nothing to execute */ + } + to->h_aliases = (char**)Alloc( + na * sizeof(char*), buf, bufsize, sizeof(char**)); + if (!to->h_aliases) { + return PR_FAILURE; + } + + /* Copy the aliases, one at a time */ + if (!from->h_aliases) { + to->h_aliases[0] = 0; + } else { + for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) { + len = strlen(*ap) + 1; + to->h_aliases[na] = Alloc(len, buf, bufsize, 0); + if (!to->h_aliases[na]) { + return PR_FAILURE; + } + memcpy(to->h_aliases[na], *ap, len); + } + to->h_aliases[na] = 0; + } + + /* Count the addresses, then allocate storage for the pointers */ + for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++) {;} /* nothing to execute */ + to->h_addr_list = (char**)Alloc( + na * sizeof(char*), buf, bufsize, sizeof(char**)); + if (!to->h_addr_list) { + return PR_FAILURE; + } + + /* Copy the addresses, one at a time */ + for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) { + to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0); + if (!to->h_addr_list[na]) { + return PR_FAILURE; + } + if (conversion != _PRIPAddrNoConversion + && from->h_addrtype == AF_INET) { + if (conversion == _PRIPAddrIPv4Mapped) { + MakeIPv4MappedAddr(*ap, to->h_addr_list[na]); + } else { + PR_ASSERT(conversion == _PRIPAddrIPv4Compat); + MakeIPv4CompatAddr(*ap, to->h_addr_list[na]); + } + } else { + memcpy(to->h_addr_list[na], *ap, to->h_length); + } + } + to->h_addr_list[na] = 0; + return PR_SUCCESS; } -#endif #if !defined(_PR_HAVE_GETPROTO_R) /* @@ -595,35 +590,43 @@ static void AssignAliases(struct protoent *Protoent, char** aliases) static PRStatus CopyProtoent( struct protoent *from, char *buf, PRIntn bufsize, PRProtoEnt *to) { - PRIntn len, na; - char **ap; - - /* Do the easy stuff */ - to->p_num = from->p_proto; - - /* Copy the official name */ - if (!from->p_name) return PR_FAILURE; - len = strlen(from->p_name) + 1; - to->p_name = Alloc(len, &buf, &bufsize, 0); - if (!to->p_name) return PR_FAILURE; - memcpy(to->p_name, from->p_name, len); - - /* Count the aliases, then allocate storage for the pointers */ - for (na = 1, ap = from->p_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */ - to->p_aliases = (char**)Alloc( - na * sizeof(char*), &buf, &bufsize, sizeof(char**)); - if (!to->p_aliases) return PR_FAILURE; - - /* Copy the aliases, one at a time */ - for (na = 0, ap = from->p_aliases; *ap != 0; na++, ap++) { - len = strlen(*ap) + 1; - to->p_aliases[na] = Alloc(len, &buf, &bufsize, 0); - if (!to->p_aliases[na]) return PR_FAILURE; - memcpy(to->p_aliases[na], *ap, len); - } - to->p_aliases[na] = 0; - - return PR_SUCCESS; + PRIntn len, na; + char **ap; + + /* Do the easy stuff */ + to->p_num = from->p_proto; + + /* Copy the official name */ + if (!from->p_name) { + return PR_FAILURE; + } + len = strlen(from->p_name) + 1; + to->p_name = Alloc(len, &buf, &bufsize, 0); + if (!to->p_name) { + return PR_FAILURE; + } + memcpy(to->p_name, from->p_name, len); + + /* Count the aliases, then allocate storage for the pointers */ + for (na = 1, ap = from->p_aliases; *ap != 0; na++, ap++) {;} /* nothing to execute */ + to->p_aliases = (char**)Alloc( + na * sizeof(char*), &buf, &bufsize, sizeof(char**)); + if (!to->p_aliases) { + return PR_FAILURE; + } + + /* Copy the aliases, one at a time */ + for (na = 0, ap = from->p_aliases; *ap != 0; na++, ap++) { + len = strlen(*ap) + 1; + to->p_aliases[na] = Alloc(len, &buf, &bufsize, 0); + if (!to->p_aliases[na]) { + return PR_FAILURE; + } + memcpy(to->p_aliases[na], *ap, len); + } + to->p_aliases[na] = 0; + + return PR_SUCCESS; } #endif /* !defined(_PR_HAVE_GETPROTO_R) */ @@ -631,7 +634,7 @@ static PRStatus CopyProtoent( * ################################################################# * NOTE: tmphe, tmpbuf, bufsize, h, and h_err are local variables * or arguments of PR_GetHostByName, PR_GetIPNodeByName, and - * PR_GetHostByAddr. DO NOT CHANGE THE NAMES OF THESE LOCAL + * PR_GetHostByAddr. DO NOT CHANGE THE NAMES OF THESE LOCAL * VARIABLES OR ARGUMENTS. * ################################################################# */ @@ -665,8 +668,8 @@ static PRStatus CopyProtoent( PR_IMPLEMENT(PRStatus) PR_GetHostByName( const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp) { - struct hostent *h; - PRStatus rv = PR_FAILURE; + struct hostent *h; + PRStatus rv = PR_FAILURE; #if defined(_PR_HAVE_GETHOST_R) char localbuf[PR_NETDB_BUF_SIZE]; char *tmpbuf; @@ -674,7 +677,9 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName( int h_err; #endif - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } #if defined(_PR_HAVE_GETHOST_R) tmpbuf = localbuf; @@ -689,35 +694,37 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName( } #endif - LOCK_DNS(); + LOCK_DNS(); - h = GETHOSTBYNAME(name); - - if (NULL == h) - { - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); - } - else - { - _PRIPAddrConversion conversion = _PRIPAddrNoConversion; - rv = CopyHostent(h, &buf, &bufsize, conversion, hp); - if (PR_SUCCESS != rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } - UNLOCK_DNS(); + h = GETHOSTBYNAME(name); + + if (NULL == h) + { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); + } + else + { + _PRIPAddrConversion conversion = _PRIPAddrNoConversion; + rv = CopyHostent(h, &buf, &bufsize, conversion, hp); + if (PR_SUCCESS != rv) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + } + UNLOCK_DNS(); #if defined(_PR_HAVE_GETHOST_R) - if (tmpbuf != localbuf) + if (tmpbuf != localbuf) { PR_Free(tmpbuf); + } #endif - return rv; + return rv; } #if !defined(_PR_INET6) && \ defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) typedef struct hostent * (*_pr_getipnodebyname_t)(const char *, int, - int, int *); + int, int *); typedef struct hostent * (*_pr_getipnodebyaddr_t)(const void *, size_t, - int, int *); + int, int *); typedef void (*_pr_freehostent_t)(struct hostent *); static void * _pr_getipnodebyname_fp; static void * _pr_getipnodebyaddr_fp; @@ -730,7 +737,7 @@ static void * _pr_freehostent_fp; PRStatus _pr_find_getipnodebyname(void) { - PRLibrary *lib; + PRLibrary *lib; PRStatus rv; #define GETIPNODEBYNAME "getipnodebyname" #define GETIPNODEBYADDR "getipnodebyaddr" @@ -741,15 +748,19 @@ _pr_find_getipnodebyname(void) _pr_freehostent_fp = PR_FindSymbol(lib, FREEHOSTENT); if (NULL != _pr_freehostent_fp) { _pr_getipnodebyaddr_fp = PR_FindSymbol(lib, GETIPNODEBYADDR); - if (NULL != _pr_getipnodebyaddr_fp) + if (NULL != _pr_getipnodebyaddr_fp) { rv = PR_SUCCESS; - else + } + else { rv = PR_FAILURE; - } else + } + } else { rv = PR_FAILURE; + } (void)PR_UnloadLibrary(lib); - } else + } else { rv = PR_FAILURE; + } return rv; } #endif @@ -767,15 +778,17 @@ static PRStatus AppendV4AddrsToHostent( PRIntn na, na_old; char **ap; char **new_addr_list; - + /* Count the addresses, then grow storage for the pointers */ for (na_old = 0, ap = to->h_addr_list; *ap != 0; na_old++, ap++) - {;} /* nothing to execute */ + {;} /* nothing to execute */ for (na = na_old + 1, ap = from->h_addr_list; *ap != 0; na++, ap++) - {;} /* nothing to execute */ + {;} /* nothing to execute */ new_addr_list = (char**)Alloc( - na * sizeof(char*), buf, bufsize, sizeof(char**)); - if (!new_addr_list) return PR_FAILURE; + na * sizeof(char*), buf, bufsize, sizeof(char**)); + if (!new_addr_list) { + return PR_FAILURE; + } /* Copy the V6 addresses, one at a time */ for (na = 0, ap = to->h_addr_list; *ap != 0; na++, ap++) { @@ -786,7 +799,9 @@ static PRStatus AppendV4AddrsToHostent( /* Copy the V4 addresses, one at a time */ for (ap = from->h_addr_list; *ap != 0; na++, ap++) { to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0); - if (!to->h_addr_list[na]) return PR_FAILURE; + if (!to->h_addr_list[na]) { + return PR_FAILURE; + } MakeIPv4MappedAddr(*ap, to->h_addr_list[na]); } to->h_addr_list[na] = 0; @@ -798,8 +813,8 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName( const char *name, PRUint16 af, PRIntn flags, char *buf, PRIntn bufsize, PRHostEnt *hp) { - struct hostent *h = 0; - PRStatus rv = PR_FAILURE; + struct hostent *h = 0; + PRStatus rv = PR_FAILURE; #if defined(_PR_HAVE_GETHOST_R) char localbuf[PR_NETDB_BUF_SIZE]; char *tmpbuf; @@ -807,15 +822,17 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName( int h_err; #endif #if defined(_PR_HAVE_GETIPNODEBYNAME) - PRUint16 md_af = af; - int error_num; - int tmp_flags = 0; + PRUint16 md_af = af; + int error_num; + int tmp_flags = 0; #endif #if defined(_PR_HAVE_GETHOSTBYNAME2) PRBool did_af_inet = PR_FALSE; #endif - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (af != PR_AF_INET && af != PR_AF_INET6) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); @@ -830,28 +847,35 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName( * machine going from offline to online. */ if (!_pr_have_inet_if && !_pr_have_inet6_if) { - _pr_QueryNetIfs(); + _pr_QueryNetIfs(); #ifdef DEBUG_QUERY_IFS - if (_pr_have_inet_if) - printf("Have IPv4 source address\n"); - if (_pr_have_inet6_if) - printf("Have IPv6 source address\n"); + if (_pr_have_inet_if) { + printf("Have IPv4 source address\n"); + } + if (_pr_have_inet6_if) { + printf("Have IPv6 source address\n"); + } #endif } PR_Unlock(_pr_query_ifs_lock); #endif #if defined(_PR_HAVE_GETIPNODEBYNAME) - if (flags & PR_AI_V4MAPPED) - tmp_flags |= AI_V4MAPPED; - if (flags & PR_AI_ADDRCONFIG) - tmp_flags |= AI_ADDRCONFIG; - if (flags & PR_AI_ALL) - tmp_flags |= AI_ALL; - if (af == PR_AF_INET6) - md_af = AF_INET6; - else - md_af = af; + if (flags & PR_AI_V4MAPPED) { + tmp_flags |= AI_V4MAPPED; + } + if (flags & PR_AI_ADDRCONFIG) { + tmp_flags |= AI_ADDRCONFIG; + } + if (flags & PR_AI_ALL) { + tmp_flags |= AI_ALL; + } + if (af == PR_AF_INET6) { + md_af = AF_INET6; + } + else { + md_af = af; + } #endif #if defined(_PR_HAVE_GETHOST_R) @@ -876,12 +900,12 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName( if ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet6_if) { #ifdef _PR_INET6_PROBE - if (_pr_ipv6_is_present()) + if (_pr_ipv6_is_present()) #endif - h = GETHOSTBYNAME2(name, AF_INET6); + h = GETHOSTBYNAME2(name, AF_INET6); } if ((NULL == h) && (flags & PR_AI_V4MAPPED) - && ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if)) + && ((flags & PR_AI_ADDRCONFIG) == 0 || _pr_have_inet_if)) { did_af_inet = PR_TRUE; h = GETHOSTBYNAME2(name, AF_INET); @@ -899,97 +923,106 @@ PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName( h = getipnodebyname(name, md_af, tmp_flags, &error_num); #else #error "Unknown name-to-address translation function" -#endif /* _PR_HAVE_GETHOSTBYNAME2 */ +#endif /* _PR_HAVE_GETHOSTBYNAME2 */ #elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) if (_pr_ipv6_is_present()) { #ifdef PR_GETIPNODE_NOT_THREADSAFE LOCK_DNS(); #endif - h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num); + h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num); } else { LOCK_DNS(); - h = GETHOSTBYNAME(name); + h = GETHOSTBYNAME(name); } #else /* _PR_INET6 */ LOCK_DNS(); h = GETHOSTBYNAME(name); #endif /* _PR_INET6 */ - - if (NULL == h) - { + + if (NULL == h) + { #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); #elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) - if (_pr_ipv6_is_present()) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); - else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); + if (_pr_ipv6_is_present()) { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); + } + else { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); + } #else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); #endif - } - else - { - _PRIPAddrConversion conversion = _PRIPAddrNoConversion; + } + else + { + _PRIPAddrConversion conversion = _PRIPAddrNoConversion; - if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped; - rv = CopyHostent(h, &buf, &bufsize, conversion, hp); - if (PR_SUCCESS != rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + if (af == PR_AF_INET6) { + conversion = _PRIPAddrIPv4Mapped; + } + rv = CopyHostent(h, &buf, &bufsize, conversion, hp); + if (PR_SUCCESS != rv) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME) - freehostent(h); + freehostent(h); #elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) - if (_pr_ipv6_is_present()) - (*((_pr_freehostent_t)_pr_freehostent_fp))(h); + if (_pr_ipv6_is_present()) { + (*((_pr_freehostent_t)_pr_freehostent_fp))(h); + } #endif #if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2) - if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED) - && ((flags & PR_AI_ALL) - || ((flags & PR_AI_ADDRCONFIG) && _pr_have_inet_if)) - && !did_af_inet && (h = GETHOSTBYNAME2(name, AF_INET)) != 0) { - rv = AppendV4AddrsToHostent(h, &buf, &bufsize, hp); - if (PR_SUCCESS != rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } + if ((PR_SUCCESS == rv) && (flags & PR_AI_V4MAPPED) + && ((flags & PR_AI_ALL) + || ((flags & PR_AI_ADDRCONFIG) && _pr_have_inet_if)) + && !did_af_inet && (h = GETHOSTBYNAME2(name, AF_INET)) != 0) { + rv = AppendV4AddrsToHostent(h, &buf, &bufsize, hp); + if (PR_SUCCESS != rv) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + } #endif - } + } /* Must match the convoluted logic above for LOCK_DNS() */ #ifdef _PR_INET6 #ifdef _PR_HAVE_GETHOSTBYNAME2 UNLOCK_DNS(); -#endif /* _PR_HAVE_GETHOSTBYNAME2 */ +#endif /* _PR_HAVE_GETHOSTBYNAME2 */ #elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME) #ifdef PR_GETIPNODE_NOT_THREADSAFE UNLOCK_DNS(); #else - if (!_pr_ipv6_is_present()) + if (!_pr_ipv6_is_present()) { UNLOCK_DNS(); + } #endif #else /* _PR_INET6 */ UNLOCK_DNS(); #endif /* _PR_INET6 */ #if defined(_PR_HAVE_GETHOST_R) - if (tmpbuf != localbuf) + if (tmpbuf != localbuf) { PR_Free(tmpbuf); + } #endif - return rv; + return rv; } PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry) { - struct hostent *h; - PRStatus rv = PR_FAILURE; - const void *addr; - PRUint32 tmp_ip; - int addrlen; - PRInt32 af; + struct hostent *h; + PRStatus rv = PR_FAILURE; + const void *addr; + PRUint32 tmp_ip; + int addrlen; + PRInt32 af; #if defined(_PR_HAVE_GETHOST_R) char localbuf[PR_NETDB_BUF_SIZE]; char *tmpbuf; @@ -997,55 +1030,58 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( int h_err; #endif #if defined(_PR_HAVE_GETIPNODEBYADDR) - int error_num; + int error_num; #endif - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } - if (hostaddr->raw.family == PR_AF_INET6) - { + if (hostaddr->raw.family == PR_AF_INET6) + { #if defined(_PR_INET6_PROBE) - af = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; + af = _pr_ipv6_is_present() ? AF_INET6 : AF_INET; #elif defined(_PR_INET6) - af = AF_INET6; + af = AF_INET6; #else - af = AF_INET; + af = AF_INET; #endif #if defined(_PR_GHBA_DISALLOW_V4MAPPED) - if (_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) - af = AF_INET; -#endif - } - else - { - PR_ASSERT(hostaddr->raw.family == AF_INET); - af = AF_INET; - } - if (hostaddr->raw.family == PR_AF_INET6) { + if (_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) { + af = AF_INET; + } +#endif + } + else + { + PR_ASSERT(hostaddr->raw.family == AF_INET); + af = AF_INET; + } + if (hostaddr->raw.family == PR_AF_INET6) { #if defined(_PR_INET6) || defined(_PR_INET6_PROBE) - if (af == AF_INET6) { - addr = &hostaddr->ipv6.ip; - addrlen = sizeof(hostaddr->ipv6.ip); - } - else -#endif - { - PR_ASSERT(af == AF_INET); - if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return rv; - } - tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *) - &hostaddr->ipv6.ip); - addr = &tmp_ip; - addrlen = sizeof(tmp_ip); - } - } else { - PR_ASSERT(hostaddr->raw.family == AF_INET); - PR_ASSERT(af == AF_INET); - addr = &hostaddr->inet.ip; - addrlen = sizeof(hostaddr->inet.ip); - } + if (af == AF_INET6) { + addr = &hostaddr->ipv6.ip; + addrlen = sizeof(hostaddr->ipv6.ip); + } + else +#endif + { + PR_ASSERT(af == AF_INET); + if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return rv; + } + tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *) + &hostaddr->ipv6.ip); + addr = &tmp_ip; + addrlen = sizeof(tmp_ip); + } + } else { + PR_ASSERT(hostaddr->raw.family == AF_INET); + PR_ASSERT(af == AF_INET); + addr = &hostaddr->inet.ip; + addrlen = sizeof(hostaddr->inet.ip); + } #if defined(_PR_HAVE_GETHOST_R) tmpbuf = localbuf; @@ -1062,63 +1098,66 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( /* Do not need to lock the DNS lock if getipnodebyaddr() is called */ #if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6) - h = getipnodebyaddr(addr, addrlen, af, &error_num); + h = getipnodebyaddr(addr, addrlen, af, &error_num); #elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE) if (_pr_ipv6_is_present()) { #ifdef PR_GETIPNODE_NOT_THREADSAFE LOCK_DNS(); #endif - h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen, - af, &error_num); + h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen, + af, &error_num); } - else + else { LOCK_DNS(); - h = GETHOSTBYADDR(addr, addrlen, af); + h = GETHOSTBYADDR(addr, addrlen, af); } -#else /* _PR_HAVE_GETIPNODEBYADDR */ +#else /* _PR_HAVE_GETIPNODEBYADDR */ LOCK_DNS(); - h = GETHOSTBYADDR(addr, addrlen, af); + h = GETHOSTBYADDR(addr, addrlen, af); #endif /* _PR_HAVE_GETIPNODEBYADDR */ - if (NULL == h) - { + if (NULL == h) + { #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); #elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) - if (_pr_ipv6_is_present()) - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); - else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); + if (_pr_ipv6_is_present()) { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num); + } + else { + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); + } #else - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); -#endif - } - else - { - _PRIPAddrConversion conversion = _PRIPAddrNoConversion; - if (hostaddr->raw.family == PR_AF_INET6) { - if (af == AF_INET) { - if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*) - &hostaddr->ipv6.ip)) { - conversion = _PRIPAddrIPv4Mapped; - } else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *) - &hostaddr->ipv6.ip)) { - conversion = _PRIPAddrIPv4Compat; - } - } - } - rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry); - if (PR_SUCCESS != rv) { - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO()); +#endif + } + else + { + _PRIPAddrConversion conversion = _PRIPAddrNoConversion; + if (hostaddr->raw.family == PR_AF_INET6) { + if (af == AF_INET) { + if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*) + &hostaddr->ipv6.ip)) { + conversion = _PRIPAddrIPv4Mapped; + } else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *) + &hostaddr->ipv6.ip)) { + conversion = _PRIPAddrIPv4Compat; + } + } + } + rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry); + if (PR_SUCCESS != rv) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR) - freehostent(h); + freehostent(h); #elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR) - if (_pr_ipv6_is_present()) - (*((_pr_freehostent_t)_pr_freehostent_fp))(h); + if (_pr_ipv6_is_present()) { + (*((_pr_freehostent_t)_pr_freehostent_fp))(h); + } #endif - } + } /* Must match the convoluted logic above for LOCK_DNS() */ #if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6) @@ -1126,19 +1165,21 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( #ifdef PR_GETIPNODE_NOT_THREADSAFE UNLOCK_DNS(); #else - if (!_pr_ipv6_is_present()) + if (!_pr_ipv6_is_present()) { UNLOCK_DNS(); + } #endif -#else /* _PR_HAVE_GETIPNODEBYADDR */ +#else /* _PR_HAVE_GETIPNODEBYADDR */ UNLOCK_DNS(); #endif /* _PR_HAVE_GETIPNODEBYADDR */ #if defined(_PR_HAVE_GETHOST_R) - if (tmpbuf != localbuf) + if (tmpbuf != localbuf) { PR_Free(tmpbuf); + } #endif - return rv; + return rv; } /******************************************************************************/ @@ -1169,12 +1210,12 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr( static struct protoent *getprotobyname_r(const char* name) { - return getprotobyname(name); + return getprotobyname(name); } /* getprotobyname_r */ static struct protoent *getprotobynumber_r(PRInt32 number) { - return getprotobynumber(number); + return getprotobynumber(number); } /* getprotobynumber_r */ #endif /* !defined(_PR_HAVE_GETPROTO_R) */ @@ -1182,12 +1223,14 @@ static struct protoent *getprotobynumber_r(PRInt32 number) PR_IMPLEMENT(PRStatus) PR_GetProtoByName( const char* name, char* buffer, PRInt32 buflen, PRProtoEnt* result) { - PRStatus rv = PR_SUCCESS; + PRStatus rv = PR_SUCCESS; #if defined(_PR_HAVE_GETPROTO_R) - struct protoent* res = (struct protoent*)result; + struct protoent* res = (struct protoent*)result; #endif - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } #if defined(_PR_HAVE_GETPROTO_R_INT) { @@ -1225,7 +1268,7 @@ PR_IMPLEMENT(PRStatus) PR_GetProtoByName( ** at least the size of a struct protoent_data. */ memset(buffer, 0, buflen); - if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer)) + if (-1 == getprotobyname_r(name, res, (struct protoent_data*)buffer)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; @@ -1238,27 +1281,24 @@ PR_IMPLEMENT(PRStatus) PR_GetProtoByName( return PR_FAILURE; } #else /* do it the hard way */ - { - struct protoent *staticBuf; - PR_Lock(_getproto_lock); - staticBuf = getprotobyname_r(name); - if (NULL == staticBuf) - { - rv = PR_FAILURE; - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - } - else - { -#if defined(SYMBIAN) - char* aliases[2]; - AssignAliases(staticBuf, aliases); -#endif - rv = CopyProtoent(staticBuf, buffer, buflen, result); - if (PR_FAILURE == rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } - PR_Unlock(_getproto_lock); - } + { + struct protoent *staticBuf; + PR_Lock(_getproto_lock); + staticBuf = getprotobyname_r(name); + if (NULL == staticBuf) + { + rv = PR_FAILURE; + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + } + else + { + rv = CopyProtoent(staticBuf, buffer, buflen, result); + if (PR_FAILURE == rv) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + } + PR_Unlock(_getproto_lock); + } #endif /* all that */ return rv; } @@ -1266,12 +1306,14 @@ PR_IMPLEMENT(PRStatus) PR_GetProtoByName( PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber( PRInt32 number, char* buffer, PRInt32 buflen, PRProtoEnt* result) { - PRStatus rv = PR_SUCCESS; + PRStatus rv = PR_SUCCESS; #if defined(_PR_HAVE_GETPROTO_R) - struct protoent* res = (struct protoent*)result; + struct protoent* res = (struct protoent*)result; #endif - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } #if defined(_PR_HAVE_GETPROTO_R_INT) { @@ -1309,7 +1351,7 @@ PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber( ** The buffer needs to be zero'd for these OS's. */ memset(buffer, 0, buflen); - if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer)) + if (-1 == getprotobynumber_r(number, res, (struct protoent_data*)buffer)) { PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); return PR_FAILURE; @@ -1322,27 +1364,24 @@ PR_IMPLEMENT(PRStatus) PR_GetProtoByNumber( return PR_FAILURE; } #else /* do it the hard way */ - { - struct protoent *staticBuf; - PR_Lock(_getproto_lock); - staticBuf = getprotobynumber_r(number); - if (NULL == staticBuf) - { - rv = PR_FAILURE; - PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); - } - else - { -#if defined(SYMBIAN) - char* aliases[2]; - AssignAliases(staticBuf, aliases); -#endif - rv = CopyProtoent(staticBuf, buffer, buflen, result); - if (PR_FAILURE == rv) - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - } - PR_Unlock(_getproto_lock); - } + { + struct protoent *staticBuf; + PR_Lock(_getproto_lock); + staticBuf = getprotobynumber_r(number); + if (NULL == staticBuf) + { + rv = PR_FAILURE; + PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_ERRNO()); + } + else + { + rv = CopyProtoent(staticBuf, buffer, buflen, result); + if (PR_FAILURE == rv) { + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + } + } + PR_Unlock(_getproto_lock); + } #endif /* all that crap */ return rv; @@ -1360,8 +1399,9 @@ PRUintn _PR_NetAddrSize(const PRNetAddr* addr) * we take the size of struct sockaddr_in6 instead of * addr->ipv6. */ - if (AF_INET == addr->raw.family) + if (AF_INET == addr->raw.family) { addrsize = sizeof(addr->inet); + } else if (PR_AF_INET6 == addr->raw.family) #if defined(_PR_INET6) addrsize = sizeof(struct sockaddr_in6); @@ -1382,7 +1422,9 @@ PRUintn _PR_NetAddrSize(const PRNetAddr* addr) addrsize = sizeof(addr->local); } #endif - else addrsize = 0; + else { + addrsize = 0; + } return addrsize; } /* _PR_NetAddrSize */ @@ -1392,15 +1434,17 @@ PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt( { void *addr = hostEnt->h_addr_list[enumIndex++]; memset(address, 0, sizeof(PRNetAddr)); - if (NULL == addr) enumIndex = 0; + if (NULL == addr) { + enumIndex = 0; + } else { address->raw.family = hostEnt->h_addrtype; if (PR_AF_INET6 == hostEnt->h_addrtype) { address->ipv6.port = htons(port); - address->ipv6.flowinfo = 0; - address->ipv6.scope_id = 0; + address->ipv6.flowinfo = 0; + address->ipv6.scope_id = 0; memcpy(&address->ipv6.ip, addr, hostEnt->h_length); } else @@ -1417,25 +1461,29 @@ PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr( PRNetAddrValue val, PRUint16 port, PRNetAddr *addr) { PRStatus rv = PR_SUCCESS; - if (!_pr_initialized) _PR_ImplicitInitialization(); - - if (val != PR_IpAddrNull) memset(addr, 0, sizeof(*addr)); - addr->inet.family = AF_INET; - addr->inet.port = htons(port); - switch (val) - { - case PR_IpAddrNull: - break; /* don't overwrite the address */ - case PR_IpAddrAny: - addr->inet.ip = htonl(INADDR_ANY); - break; - case PR_IpAddrLoopback: - addr->inet.ip = htonl(INADDR_LOOPBACK); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; - } + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } + + if (val != PR_IpAddrNull) { + memset(addr, 0, sizeof(*addr)); + } + addr->inet.family = AF_INET; + addr->inet.port = htons(port); + switch (val) + { + case PR_IpAddrNull: + break; /* don't overwrite the address */ + case PR_IpAddrAny: + addr->inet.ip = htonl(INADDR_ANY); + break; + case PR_IpAddrLoopback: + addr->inet.ip = htonl(INADDR_LOOPBACK); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; + } return rv; } /* PR_InitializeNetAddr */ @@ -1443,48 +1491,54 @@ PR_IMPLEMENT(PRStatus) PR_SetNetAddr( PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr) { PRStatus rv = PR_SUCCESS; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (af == PR_AF_INET6) { - if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->ipv6)); + if (val != PR_IpAddrNull) { + memset(addr, 0, sizeof(addr->ipv6)); + } addr->ipv6.family = af; addr->ipv6.port = htons(port); addr->ipv6.flowinfo = 0; addr->ipv6.scope_id = 0; switch (val) { - case PR_IpAddrNull: - break; /* don't overwrite the address */ - case PR_IpAddrAny: - addr->ipv6.ip = _pr_in6addr_any; - break; - case PR_IpAddrLoopback: - addr->ipv6.ip = _pr_in6addr_loopback; - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; + case PR_IpAddrNull: + break; /* don't overwrite the address */ + case PR_IpAddrAny: + addr->ipv6.ip = _pr_in6addr_any; + break; + case PR_IpAddrLoopback: + addr->ipv6.ip = _pr_in6addr_loopback; + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; } } else { - if (val != PR_IpAddrNull) memset(addr, 0, sizeof(addr->inet)); + if (val != PR_IpAddrNull) { + memset(addr, 0, sizeof(addr->inet)); + } addr->inet.family = af; addr->inet.port = htons(port); switch (val) { - case PR_IpAddrNull: - break; /* don't overwrite the address */ - case PR_IpAddrAny: - addr->inet.ip = htonl(INADDR_ANY); - break; - case PR_IpAddrLoopback: - addr->inet.ip = htonl(INADDR_LOOPBACK); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - rv = PR_FAILURE; + case PR_IpAddrNull: + break; /* don't overwrite the address */ + case PR_IpAddrAny: + addr->inet.ip = htonl(INADDR_ANY); + break; + case PR_IpAddrLoopback: + addr->inet.ip = htonl(INADDR_LOOPBACK); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + rv = PR_FAILURE; } } return rv; @@ -1495,25 +1549,25 @@ PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val) { if (addr->raw.family == PR_AF_INET6) { if (val == PR_IpAddrAny) { - if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) { - return PR_TRUE; - } + if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) { + return PR_TRUE; + } if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) == htonl(INADDR_ANY)) { return PR_TRUE; - } + } } else if (val == PR_IpAddrLoopback) { if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) { - return PR_TRUE; - } + return PR_TRUE; + } if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip) && _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip) == htonl(INADDR_LOOPBACK)) { return PR_TRUE; - } + } } else if (val == PR_IpAddrV4Mapped - && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) { + && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) { return PR_TRUE; } } else { @@ -1537,7 +1591,7 @@ static const unsigned char index_hex[256] = { XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,XX,XX, XX,XX,XX,XX, XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX, @@ -1570,16 +1624,22 @@ static int StringToV6Addr(const char *string, PRIPv6Addr *addr) /* Handle initial (double) colon */ if (*s == ':') { - if (s[1] != ':') return 0; + if (s[1] != ':') { + return 0; + } s += 2; addr->pr_s6_addr16[0] = 0; section = double_colon = 1; } while (*s) { - if (section == 8) return 0; /* too long */ + if (section == 8) { + return 0; /* too long */ + } if (*s == ':') { - if (double_colon != -1) return 0; /* two double colons */ + if (double_colon != -1) { + return 0; /* two double colons */ + } addr->pr_s6_addr16[section++] = 0; double_colon = section; s++; @@ -1589,70 +1649,96 @@ static int StringToV6Addr(const char *string, PRIPv6Addr *addr) val = (val << 4) + index_hex[*s++]; } if (*s == '.') { - if (len == 0) return 0; /* nothing between : and . */ + if (len == 0) { + return 0; /* nothing between : and . */ + } break; } if (*s == ':') { s++; - if (!*s) return 0; /* cannot end with single colon */ + if (!*s) { + return 0; /* cannot end with single colon */ + } } else if (*s) { return 0; /* bad character */ } addr->pr_s6_addr16[section++] = htons((unsigned short)val); } - + if (*s == '.') { /* Have a trailing v4 format address */ - if (section > 6) return 0; /* not enough room */ + if (section > 6) { + return 0; /* not enough room */ + } /* * The number before the '.' is decimal, but we parsed it * as hex. That means it is in BCD. Check it for validity * and convert it to binary. */ - if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) return 0; + if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) { + return 0; + } val = (val >> 8) * 100 + ((val >> 4) & 0xf) * 10 + (val & 0xf); addr->pr_s6_addr[2 * section] = val; s++; val = index_hex[*s++]; - if (val > 9) return 0; + if (val > 9) { + return 0; + } while (*s >= '0' && *s <= '9') { val = val * 10 + *s++ - '0'; - if (val > 255) return 0; + if (val > 255) { + return 0; + } + } + if (*s != '.') { + return 0; /* must have exactly 4 decimal numbers */ } - if (*s != '.') return 0; /* must have exactly 4 decimal numbers */ addr->pr_s6_addr[2 * section + 1] = val; section++; s++; val = index_hex[*s++]; - if (val > 9) return 0; + if (val > 9) { + return 0; + } while (*s >= '0' && *s <= '9') { val = val * 10 + *s++ - '0'; - if (val > 255) return 0; + if (val > 255) { + return 0; + } + } + if (*s != '.') { + return 0; /* must have exactly 4 decimal numbers */ } - if (*s != '.') return 0; /* must have exactly 4 decimal numbers */ addr->pr_s6_addr[2 * section] = val; s++; val = index_hex[*s++]; - if (val > 9) return 0; + if (val > 9) { + return 0; + } while (*s >= '0' && *s <= '9') { val = val * 10 + *s++ - '0'; - if (val > 255) return 0; + if (val > 255) { + return 0; + } + } + if (*s) { + return 0; /* must have exactly 4 decimal numbers */ } - if (*s) return 0; /* must have exactly 4 decimal numbers */ addr->pr_s6_addr[2 * section + 1] = val; section++; } - + if (double_colon != -1) { /* Stretch the double colon */ int tosection; int ncopy = section - double_colon; for (tosection = 7; ncopy--; tosection--) { - addr->pr_s6_addr16[tosection] = + addr->pr_s6_addr16[tosection] = addr->pr_s6_addr16[double_colon + ncopy]; } while (tosection >= double_colon) { @@ -1726,20 +1812,36 @@ static const char *V6AddrToString( STUFF('f'); STUFF(':'); } - if (addr->pr_s6_addr[12] > 99) STUFF(addr->pr_s6_addr[12]/100 + '0'); - if (addr->pr_s6_addr[12] > 9) STUFF((addr->pr_s6_addr[12]%100)/10 + '0'); + if (addr->pr_s6_addr[12] > 99) { + STUFF(addr->pr_s6_addr[12]/100 + '0'); + } + if (addr->pr_s6_addr[12] > 9) { + STUFF((addr->pr_s6_addr[12]%100)/10 + '0'); + } STUFF(addr->pr_s6_addr[12]%10 + '0'); STUFF('.'); - if (addr->pr_s6_addr[13] > 99) STUFF(addr->pr_s6_addr[13]/100 + '0'); - if (addr->pr_s6_addr[13] > 9) STUFF((addr->pr_s6_addr[13]%100)/10 + '0'); + if (addr->pr_s6_addr[13] > 99) { + STUFF(addr->pr_s6_addr[13]/100 + '0'); + } + if (addr->pr_s6_addr[13] > 9) { + STUFF((addr->pr_s6_addr[13]%100)/10 + '0'); + } STUFF(addr->pr_s6_addr[13]%10 + '0'); STUFF('.'); - if (addr->pr_s6_addr[14] > 99) STUFF(addr->pr_s6_addr[14]/100 + '0'); - if (addr->pr_s6_addr[14] > 9) STUFF((addr->pr_s6_addr[14]%100)/10 + '0'); + if (addr->pr_s6_addr[14] > 99) { + STUFF(addr->pr_s6_addr[14]/100 + '0'); + } + if (addr->pr_s6_addr[14] > 9) { + STUFF((addr->pr_s6_addr[14]%100)/10 + '0'); + } STUFF(addr->pr_s6_addr[14]%10 + '0'); STUFF('.'); - if (addr->pr_s6_addr[15] > 99) STUFF(addr->pr_s6_addr[15]/100 + '0'); - if (addr->pr_s6_addr[15] > 9) STUFF((addr->pr_s6_addr[15]%100)/10 + '0'); + if (addr->pr_s6_addr[15] > 99) { + STUFF(addr->pr_s6_addr[15]/100 + '0'); + } + if (addr->pr_s6_addr[15] > 9) { + STUFF((addr->pr_s6_addr[15]%100)/10 + '0'); + } STUFF(addr->pr_s6_addr[15]%10 + '0'); STUFF('\0'); return bufcopy; @@ -1765,11 +1867,13 @@ static const char *V6AddrToString( } STUFF(basis_hex[val & 0xf]); section++; - if (section < 8 && section != double_colon) STUFF(':'); + if (section < 8 && section != double_colon) { + STUFF(':'); + } } STUFF('\0'); return bufcopy; -#undef STUFF +#undef STUFF } #endif /* !_PR_HAVE_INET_NTOP */ @@ -1785,10 +1889,18 @@ PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr) memcpy(dstp + 12,(char *) &v4addr, 4); } -PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); } -PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); } -PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); } -PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); } +PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { + return ntohs(n); +} +PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { + return ntohl(n); +} +PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { + return htons(n); +} +PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { + return htonl(n); +} PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n) { #ifdef IS_BIG_ENDIAN @@ -1849,23 +1961,23 @@ typedef struct addrinfo PRADDRINFO; typedef struct addrinfo PRADDRINFO; -/* getaddrinfo/freeaddrinfo/getnameinfo prototypes */ +/* getaddrinfo/freeaddrinfo/getnameinfo prototypes */ #if defined(WIN32) #define FUNC_MODIFIER __stdcall #else #define FUNC_MODIFIER #endif typedef int (FUNC_MODIFIER * FN_GETADDRINFO) - (const char *nodename, - const char *servname, - const PRADDRINFO *hints, - PRADDRINFO **res); +(const char *nodename, + const char *servname, + const PRADDRINFO *hints, + PRADDRINFO **res); typedef int (FUNC_MODIFIER * FN_FREEADDRINFO) - (PRADDRINFO *ai); +(PRADDRINFO *ai); typedef int (FUNC_MODIFIER * FN_GETNAMEINFO) - (const struct sockaddr *addr, int addrlen, - char *host, int hostlen, - char *serv, int servlen, int flags); +(const struct sockaddr *addr, int addrlen, + char *host, int hostlen, + char *serv, int servlen, int flags); /* global state */ static FN_GETADDRINFO _pr_getaddrinfo = NULL; @@ -1896,15 +2008,15 @@ _pr_find_getaddrinfo(void) continue; } _pr_getaddrinfo = (FN_GETADDRINFO) - PR_FindFunctionSymbol(lib, GETADDRINFO_SYMBOL); + PR_FindFunctionSymbol(lib, GETADDRINFO_SYMBOL); if (!_pr_getaddrinfo) { PR_UnloadLibrary(lib); continue; } _pr_freeaddrinfo = (FN_FREEADDRINFO) - PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); + PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); _pr_getnameinfo = (FN_GETNAMEINFO) - PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); + PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); if (!_pr_freeaddrinfo || !_pr_getnameinfo) { PR_UnloadLibrary(lib); continue; @@ -1919,14 +2031,14 @@ _pr_find_getaddrinfo(void) * search library containing getaddrinfo for freeaddrinfo. */ _pr_getaddrinfo = (FN_GETADDRINFO) - PR_FindFunctionSymbolAndLibrary(GETADDRINFO_SYMBOL, &lib); + PR_FindFunctionSymbolAndLibrary(GETADDRINFO_SYMBOL, &lib); if (!_pr_getaddrinfo) { return PR_FAILURE; } _pr_freeaddrinfo = (FN_FREEADDRINFO) - PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); + PR_FindFunctionSymbol(lib, FREEADDRINFO_SYMBOL); _pr_getnameinfo = (FN_GETNAMEINFO) - PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); + PR_FindFunctionSymbol(lib, GETNAMEINFO_SYMBOL); PR_UnloadLibrary(lib); if (!_pr_freeaddrinfo || !_pr_getnameinfo) { return PR_FAILURE; @@ -1946,7 +2058,7 @@ _pr_find_getaddrinfo(void) #if !defined(_PR_HAVE_GETADDRINFO) || defined(_PR_INET6_PROBE) /* * If getaddrinfo does not exist, then we will fall back on - * PR_GetHostByName, which requires that we allocate a buffer for the + * PR_GetHostByName, which requires that we allocate a buffer for the * PRHostEnt data structure and its members. */ typedef struct PRAddrInfoFB { @@ -1980,8 +2092,8 @@ pr_GetAddrInfoByNameFB(const char *hostname, #endif /* !_PR_HAVE_GETADDRINFO || _PR_INET6_PROBE */ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, - PRUint16 af, - PRIntn flags) + PRUint16 af, + PRIntn flags) { /* restrict input to supported values */ if ((af != PR_AF_INET && af != PR_AF_UNSPEC) || @@ -1990,7 +2102,9 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, return NULL; } - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } #if !defined(_PR_HAVE_GETADDRINFO) return pr_GetAddrInfoByNameFB(hostname, af, flags); @@ -2011,14 +2125,15 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, */ memset(&hints, 0, sizeof(hints)); - if (!(flags & PR_AI_NOCANONNAME)) + if (!(flags & PR_AI_NOCANONNAME)) { hints.ai_flags |= AI_CANONNAME; + } #ifdef AI_ADDRCONFIG - /* + /* * Propagate AI_ADDRCONFIG to the GETADDRINFO call if PR_AI_ADDRCONFIG * is set. - * - * Need a workaround for loopback host addresses: + * + * Need a workaround for loopback host addresses: * The problem is that in glibc and Windows, AI_ADDRCONFIG applies the * existence of an outgoing network interface to IP addresses of the * loopback interface, due to a strict interpretation of the @@ -2055,8 +2170,9 @@ PR_IMPLEMENT(PRAddrInfo *) PR_GetAddrInfoByName(const char *hostname, rv = GETADDRINFO(hostname, NULL, &hints, &res); } #endif - if (rv == 0) + if (rv == 0) { return (PRAddrInfo *) res; + } PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, rv); } @@ -2068,8 +2184,9 @@ PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai) { #if defined(_PR_HAVE_GETADDRINFO) #if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) + if (!_pr_ipv6_is_present()) { PR_Free((PRAddrInfoFB *) ai); + } else #endif FREEADDRINFO((PRADDRINFO *) ai); @@ -2079,9 +2196,9 @@ PR_IMPLEMENT(void) PR_FreeAddrInfo(PRAddrInfo *ai) } PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void *iterPtr, - const PRAddrInfo *base, - PRUint16 port, - PRNetAddr *result) + const PRAddrInfo *base, + PRUint16 port, + PRNetAddr *result) { #if defined(_PR_HAVE_GETADDRINFO) PRADDRINFO *ai; @@ -2090,35 +2207,43 @@ PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void *iterPtr, /* using PRAddrInfoFB */ PRIntn iter = (PRIntn)(PRPtrdiff) iterPtr; iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result); - if (iter < 0) + if (iter < 0) { iter = 0; + } return (void *)(PRPtrdiff) iter; } #endif - if (iterPtr) + if (iterPtr) { ai = ((PRADDRINFO *) iterPtr)->ai_next; - else + } + else { ai = (PRADDRINFO *) base; + } - while (ai && ai->ai_addrlen > sizeof(PRNetAddr)) + while (ai && ai->ai_addrlen > sizeof(PRNetAddr)) { ai = ai->ai_next; + } if (ai) { /* copy sockaddr to PRNetAddr */ memcpy(result, ai->ai_addr, ai->ai_addrlen); result->raw.family = ai->ai_addr->sa_family; #ifdef _PR_INET6 - if (AF_INET6 == result->raw.family) + if (AF_INET6 == result->raw.family) { result->raw.family = PR_AF_INET6; + } #endif - if (ai->ai_addrlen < sizeof(PRNetAddr)) + if (ai->ai_addrlen < sizeof(PRNetAddr)) { memset(((char*)result)+ai->ai_addrlen, 0, sizeof(PRNetAddr) - ai->ai_addrlen); + } - if (result->raw.family == PR_AF_INET) + if (result->raw.family == PR_AF_INET) { result->inet.port = htons(port); - else + } + else { result->ipv6.port = htons(port); + } } return ai; @@ -2126,8 +2251,9 @@ PR_IMPLEMENT(void *) PR_EnumerateAddrInfo(void *iterPtr, /* using PRAddrInfoFB */ PRIntn iter = (PRIntn) iterPtr; iter = PR_EnumerateHostEnt(iter, &((PRAddrInfoFB *) base)->hostent, port, result); - if (iter < 0) + if (iter < 0) { iter = 0; + } return (void *) iter; #endif } @@ -2139,7 +2265,7 @@ PR_IMPLEMENT(const char *) PR_GetCanonNameFromAddrInfo(const PRAddrInfo *ai) if (!_pr_ipv6_is_present()) { const PRAddrInfoFB *fb = (const PRAddrInfoFB *) ai; return fb->has_cname ? fb->hostent.h_name : NULL; - } + } #endif return ((const PRADDRINFO *) ai)->ai_canonname; #else @@ -2221,7 +2347,9 @@ static PRStatus pr_StringToNetAddrFB(const char *string, PRNetAddr *addr) PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr) { - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } if (!addr || !string || !*string) { @@ -2238,12 +2366,14 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr) * and most likely others. So we only use it to convert literal IP addresses * that contain IPv6 scope IDs, which pr_inet_aton cannot convert. */ - if (!strchr(string, '%')) + if (!strchr(string, '%')) { return pr_StringToNetAddrFB(string, addr); + } #if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) + if (!_pr_ipv6_is_present()) { return pr_StringToNetAddrFB(string, addr); + } #endif return pr_StringToNetAddrGAI(string, addr); @@ -2282,7 +2412,7 @@ static PRStatus pr_NetAddrToStringGNI( addrp = &addrcopy; #endif rv = GETNAMEINFO((const struct sockaddr *)addrp, addrlen, - string, size, NULL, 0, NI_NUMERICHOST); + string, size, NULL, 0, NI_NUMERICHOST); if (rv != 0) { PR_SetError(PR_INVALID_ARGUMENT_ERROR, rv); @@ -2311,13 +2441,17 @@ static PRStatus pr_NetAddrToStringFB( } else { - if (size < 16) goto failed; - if (AF_INET != addr->raw.family) goto failed; + if (size < 16) { + goto failed; + } + if (AF_INET != addr->raw.family) { + goto failed; + } else { unsigned char *byte = (unsigned char*)&addr->inet.ip; PR_snprintf(string, size, "%u.%u.%u.%u", - byte[0], byte[1], byte[2], byte[3]); + byte[0], byte[1], byte[2], byte[3]); } } @@ -2333,14 +2467,17 @@ failed: PR_IMPLEMENT(PRStatus) PR_NetAddrToString( const PRNetAddr *addr, char *string, PRUint32 size) { - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } #if !defined(_PR_HAVE_GETADDRINFO) return pr_NetAddrToStringFB(addr, string, size); #else #if defined(_PR_INET6_PROBE) - if (!_pr_ipv6_is_present()) + if (!_pr_ipv6_is_present()) { return pr_NetAddrToStringFB(addr, string, size); + } #endif return pr_NetAddrToStringGNI(addr, string, size); #endif diff --git a/nsprpub/pr/src/misc/prolock.c b/nsprpub/pr/src/misc/prolock.c index 38b778789..77a26bb2f 100644 --- a/nsprpub/pr/src/misc/prolock.c +++ b/nsprpub/pr/src/misc/prolock.c @@ -5,18 +5,18 @@ /* ** prolock.c -- NSPR Ordered Lock -** +** ** Implement the API defined in prolock.h -** +** */ #include "prolock.h" #include "prlog.h" #include "prerror.h" -PR_IMPLEMENT(PROrderedLock *) - PR_CreateOrderedLock( - PRInt32 order, - const char *name +PR_IMPLEMENT(PROrderedLock *) +PR_CreateOrderedLock( + PRInt32 order, + const char *name ) { PR_NOT_REACHED("Not implemented"); /* Not implemented yet */ @@ -25,9 +25,9 @@ PR_IMPLEMENT(PROrderedLock *) } /* end PR_CreateOrderedLock() */ -PR_IMPLEMENT(void) - PR_DestroyOrderedLock( - PROrderedLock *lock +PR_IMPLEMENT(void) +PR_DestroyOrderedLock( + PROrderedLock *lock ) { PR_NOT_REACHED("Not implemented"); /* Not implemented yet */ @@ -35,9 +35,9 @@ PR_IMPLEMENT(void) } /* end PR_DestroyOrderedLock() */ -PR_IMPLEMENT(void) - PR_LockOrderedLock( - PROrderedLock *lock +PR_IMPLEMENT(void) +PR_LockOrderedLock( + PROrderedLock *lock ) { PR_NOT_REACHED("Not implemented"); /* Not implemented yet */ @@ -45,9 +45,9 @@ PR_IMPLEMENT(void) } /* end PR_LockOrderedLock() */ -PR_IMPLEMENT(PRStatus) - PR_UnlockOrderedLock( - PROrderedLock *lock +PR_IMPLEMENT(PRStatus) +PR_UnlockOrderedLock( + PROrderedLock *lock ) { PR_NOT_REACHED("Not implemented"); /* Not implemented yet */ diff --git a/nsprpub/pr/src/misc/prrng.c b/nsprpub/pr/src/misc/prrng.c index b5c38f82d..b3e3d4878 100644 --- a/nsprpub/pr/src/misc/prrng.c +++ b/nsprpub/pr/src/misc/prrng.c @@ -16,15 +16,15 @@ #include <string.h> #endif -PRSize _pr_CopyLowBits( - void *dst, - PRSize dstlen, - void *src, +PRSize _pr_CopyLowBits( + void *dst, + PRSize dstlen, + void *src, PRSize srclen ) { if (srclen <= dstlen) { - memcpy(dst, src, srclen); - return srclen; + memcpy(dst, src, srclen); + return srclen; } #if defined IS_BIG_ENDIAN memcpy(dst, (char*)src + (srclen - dstlen), dstlen); @@ -32,9 +32,9 @@ PRSize _pr_CopyLowBits( memcpy(dst, src, dstlen); #endif return dstlen; -} +} -PR_IMPLEMENT(PRSize) PR_GetRandomNoise( +PR_IMPLEMENT(PRSize) PR_GetRandomNoise( void *buf, PRSize size ) diff --git a/nsprpub/pr/src/misc/prsystem.c b/nsprpub/pr/src/misc/prsystem.c index eba85fb0b..825d3be0f 100644 --- a/nsprpub/pr/src/misc/prsystem.c +++ b/nsprpub/pr/src/misc/prsystem.c @@ -8,10 +8,6 @@ #include "prprf.h" #include "prlong.h" -#if defined(BEOS) -#include <kernel/OS.h> -#endif - #if defined(OS2) #define INCL_DOS #define INCL_DOSMISC @@ -71,7 +67,7 @@ PR_IMPLEMENT(char) PR_GetDirectorySepartor(void) static PRBool warn = PR_TRUE; if (warn) { warn = _PR_Obsolete("PR_GetDirectorySepartor()", - "PR_GetDirectorySeparator()"); + "PR_GetDirectorySeparator()"); } #endif return PR_GetDirectorySeparator(); @@ -86,84 +82,90 @@ PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 bufle { PRUintn len = 0; - if (!_pr_initialized) _PR_ImplicitInitialization(); + if (!_pr_initialized) { + _PR_ImplicitInitialization(); + } switch(cmd) { - case PR_SI_HOSTNAME: - case PR_SI_HOSTNAME_UNTRUNCATED: - if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen)) - return PR_FAILURE; + case PR_SI_HOSTNAME: + case PR_SI_HOSTNAME_UNTRUNCATED: + if (PR_FAILURE == _PR_MD_GETHOSTNAME(buf, (PRUintn)buflen)) { + return PR_FAILURE; + } - if (cmd == PR_SI_HOSTNAME_UNTRUNCATED) - break; - /* - * On some platforms a system does not have a hostname and - * its IP address is returned instead. The following code - * should be skipped on those platforms. - */ + if (cmd == PR_SI_HOSTNAME_UNTRUNCATED) { + break; + } + /* + * On some platforms a system does not have a hostname and + * its IP address is returned instead. The following code + * should be skipped on those platforms. + */ #ifndef _PR_GET_HOST_ADDR_AS_NAME - /* Return the unqualified hostname */ + /* Return the unqualified hostname */ while (buf[len] && (len < buflen)) { if (buf[len] == '.') { buf[len] = '\0'; break; } len += 1; - } + } #endif - break; + break; - case PR_SI_SYSNAME: - /* Return the operating system name */ + case PR_SI_SYSNAME: + /* Return the operating system name */ #if defined(XP_UNIX) || defined(WIN32) - if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) - return PR_FAILURE; + if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) { + return PR_FAILURE; + } #else - (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME); + (void)PR_snprintf(buf, buflen, _PR_SI_SYSNAME); #endif - break; + break; - case PR_SI_RELEASE: - /* Return the version of the operating system */ + case PR_SI_RELEASE: + /* Return the version of the operating system */ #if defined(XP_UNIX) || defined(WIN32) - if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) - return PR_FAILURE; + if (PR_FAILURE == _PR_MD_GETSYSINFO(cmd, buf, (PRUintn)buflen)) { + return PR_FAILURE; + } #endif #if defined(XP_OS2) - { - ULONG os2ver[2] = {0}; - DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION, - &os2ver, sizeof(os2ver)); - /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially, - Warp 4 is version 2.40.00, WSeB 2.45.00 */ - if (os2ver[0] < 30) - (void)PR_snprintf(buf, buflen, "%s%lu", - "2.", os2ver[0]); - else if (os2ver[0] < 45) - (void)PR_snprintf(buf, buflen, "%lu%s%lu", - os2ver[0]/10, ".", os2ver[1]); - else - (void)PR_snprintf(buf, buflen, "%.1f", - os2ver[0]/10.0); - } + { + ULONG os2ver[2] = {0}; + DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION, + &os2ver, sizeof(os2ver)); + /* Formatting for normal usage (2.11, 3.0, 4.0, 4.5); officially, + Warp 4 is version 2.40.00, WSeB 2.45.00 */ + if (os2ver[0] < 30) + (void)PR_snprintf(buf, buflen, "%s%lu", + "2.", os2ver[0]); + else if (os2ver[0] < 45) + (void)PR_snprintf(buf, buflen, "%lu%s%lu", + os2ver[0]/10, ".", os2ver[1]); + else + (void)PR_snprintf(buf, buflen, "%.1f", + os2ver[0]/10.0); + } #endif /* OS2 */ - break; - - case PR_SI_ARCHITECTURE: - /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/ - (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE); - break; - default: - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; + break; + + case PR_SI_ARCHITECTURE: + /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/ + (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE); + break; + default: + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; } return PR_SUCCESS; } /* ** PR_GetNumberOfProcessors() -** +** ** Implementation notes: ** Every platform does it a bit different. ** numCpus is the returned value. @@ -173,7 +175,7 @@ PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(PRSysInfo cmd, char *buf, PRUint32 bufle ** order of the if defined()s may be important, ** especially for unix variants. Do platform ** specific implementations before XP_UNIX. -** +** */ PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void ) { @@ -183,11 +185,6 @@ PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void ) GetSystemInfo( &info ); numCpus = info.dwNumberOfProcessors; -#elif defined(BEOS) - system_info sysInfo; - - get_system_info(&sysInfo); - numCpus = sysInfo.cpu_count; #elif defined(OS2) DosQuerySysInfo( QSV_NUMPROCESSORS, QSV_NUMPROCESSORS, &numCpus, sizeof(numCpus)); #elif defined(_PR_HAVE_SYSCTL) @@ -208,9 +205,7 @@ PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void ) numCpus = -1; /* set to -1 for return value on error */ _PR_MD_MAP_DEFAULT_ERROR( _MD_ERRNO() ); } -#elif defined(IRIX) - numCpus = sysconf( _SC_NPROC_ONLN ); -#elif defined(RISCOS) || defined(SYMBIAN) +#elif defined(RISCOS) numCpus = 1; #elif defined(LINUX) /* for the benefit of devices with advanced power-saving, that @@ -255,14 +250,14 @@ PR_IMPLEMENT(PRInt32) PR_GetNumberOfProcessors( void ) /* ** PR_GetPhysicalMemorySize() -** +** ** Implementation notes: ** Every platform does it a bit different. ** bytes is the returned value. ** for each platform's "if defined" section ** declare your local variable ** do your thing, assign to bytes. -** +** */ PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void) { @@ -272,8 +267,9 @@ PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void) long pageSize = sysconf(_SC_PAGESIZE); long pageCount = sysconf(_SC_PHYS_PAGES); - if (pageSize >= 0 && pageCount >= 0) + if (pageSize >= 0 && pageCount >= 0) { bytes = (PRUint64) pageSize * pageCount; + } #elif defined(NETBSD) || defined(OPENBSD) \ || defined(FREEBSD) || defined(DRAGONFLY) @@ -302,8 +298,9 @@ PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void) struct pst_static info; int result = pstat_getstatic(&info, sizeof(info), 1, 0); - if (result == 1) + if (result == 1) { bytes = (PRUint64) info.physical_memory * info.page_size; + } #elif defined(DARWIN) @@ -316,15 +313,17 @@ PR_IMPLEMENT(PRUint64) PR_GetPhysicalMemorySize(void) (host_info_t) &hInfo, &count); mach_port_deallocate(mach_task_self(), mach_host); - if (result == KERN_SUCCESS) + if (result == KERN_SUCCESS) { bytes = hInfo.max_mem; + } #elif defined(WIN32) MEMORYSTATUSEX memStat; memStat.dwLength = sizeof(memStat); - if (GlobalMemoryStatusEx(&memStat)) + if (GlobalMemoryStatusEx(&memStat)) { bytes = memStat.ullTotalPhys; + } #elif defined(OS2) diff --git a/nsprpub/pr/src/misc/prthinfo.c b/nsprpub/pr/src/misc/prthinfo.c index 2477899c3..14602df0b 100644 --- a/nsprpub/pr/src/misc/prthinfo.c +++ b/nsprpub/pr/src/misc/prthinfo.c @@ -32,8 +32,9 @@ PR_ThreadScanStackPointers(PRThread* t, */ p0 = _MD_HomeGCRegisters(t, t == current, &n); status = scanFun(t, (void**)p0, n, scanClosure); - if (status != PR_SUCCESS) + if (status != PR_SUCCESS) { return status; + } /* Scan the C stack for pointers into the GC heap */ #if defined(XP_PC) && defined(WIN16) @@ -86,7 +87,7 @@ PR_ThreadScanStackPointers(PRThread* t, { prword_t scan; prword_t limit; - + scan = (prword_t) sp; limit = (prword_t) esp; while (scan < limit) { @@ -94,16 +95,18 @@ PR_ThreadScanStackPointers(PRThread* t, test = *((prword_t **)scan); status = scanFun(t, (void**)&test, 1, scanClosure); - if (status != PR_SUCCESS) + if (status != PR_SUCCESS) { return status; + } scan += sizeof(char); } } #else if (sp < esp) { status = scanFun(t, (void**)sp, esp - sp, scanClosure); - if (status != PR_SUCCESS) + if (status != PR_SUCCESS) { return status; + } } #endif @@ -114,17 +117,19 @@ PR_ThreadScanStackPointers(PRThread* t, ** will be collected */ status = scanFun(t, (void**)&t->environment, 1, scanClosure); - if (status != PR_SUCCESS) + if (status != PR_SUCCESS) { return status; + } /* if thread is not allocated on stack, this is redundant. */ ptd = t->privateData; for (index = 0; index < t->tpdLength; index++, ptd++) { status = scanFun(t, (void**)ptd, 1, scanClosure); - if (status != PR_SUCCESS) + if (status != PR_SUCCESS) { return status; + } } - + return PR_SUCCESS; } @@ -173,9 +178,9 @@ PR_GetStackSpaceLeft(PRThread* t) sp = (PRWord*) PR_GetSP(t); esp = (PRWord*) t->stack->stackTop; - PR_ASSERT((t->stack->stackSize == 0) || - ((sp > (PRWord*)t->stack->stackBottom) && - (sp <= (PRWord*)t->stack->stackTop))); + PR_ASSERT((t->stack->stackSize == 0) || + ((sp > (PRWord*)t->stack->stackBottom) && + (sp <= (PRWord*)t->stack->stackTop))); } #else /* ! WIN16 */ #ifdef HAVE_STACK_GROWING_UP @@ -197,8 +202,8 @@ PR_GetStackSpaceLeft(PRThread* t) } esp = (PRWord*) t->stack->stackTop; if (t->stack->stackSize) { - PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && - (sp < (PRWord*)t->stack->stackTop)); + PR_ASSERT((sp > (PRWord*)t->stack->stackBottom) && + (sp < (PRWord*)t->stack->stackTop)); } #endif /* ! HAVE_STACK_GROWING_UP */ #endif /* ! WIN16 */ diff --git a/nsprpub/pr/src/misc/prtime.c b/nsprpub/pr/src/misc/prtime.c index f03786096..6d711a6b8 100644 --- a/nsprpub/pr/src/misc/prtime.c +++ b/nsprpub/pr/src/misc/prtime.c @@ -21,7 +21,7 @@ #include <errno.h> /* for EINVAL */ #include <time.h> -/* +/* * The COUNT_LEAPS macro counts the number of leap years passed by * till the start of the given year Y. At the start of the year 4 * A.D. the number of leap years passed by is 0, while at the start of @@ -204,14 +204,14 @@ ComputeGMT(PRTime time, PRExplodedTime *gmt) PR_IMPLEMENT(void) PR_ExplodeTime( - PRTime usecs, - PRTimeParamFn params, - PRExplodedTime *exploded) + PRTime usecs, + PRTimeParamFn params, + PRExplodedTime *exploded) { ComputeGMT(usecs, exploded); exploded->tm_params = params(exploded); ApplySecOffset(exploded, exploded->tm_params.tp_gmt_offset - + exploded->tm_params.tp_dst_offset); + + exploded->tm_params.tp_dst_offset); } @@ -241,9 +241,9 @@ PR_ImplodeTime(const PRExplodedTime *exploded) PR_NormalizeTime(©, PR_GMTParameters); numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year); - + numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600 - + copy.tm_min * 60 + copy.tm_sec; + + copy.tm_min * 60 + copy.tm_sec; LL_I2L(temp, numDays); LL_I2L(secPerDay, 86400); @@ -277,8 +277,9 @@ PR_ImplodeTime(const PRExplodedTime *exploded) static int IsLeapYear(PRInt16 year) { - if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) + if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) { return 1; + } return 0; } @@ -321,23 +322,26 @@ ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset) if (time->tm_month < 0) { time->tm_month = 11; time->tm_year--; - if (IsLeapYear(time->tm_year)) + if (IsLeapYear(time->tm_year)) { time->tm_yday = 365; - else + } + else { time->tm_yday = 364; + } } time->tm_mday = nDays[IsLeapYear(time->tm_year)][time->tm_month]; } time->tm_wday--; - if (time->tm_wday < 0) + if (time->tm_wday < 0) { time->tm_wday = 6; + } } else if (time->tm_hour > 23) { /* Increment mday, yday, and wday */ time->tm_hour -= 24; time->tm_mday++; time->tm_yday++; if (time->tm_mday > - nDays[IsLeapYear(time->tm_year)][time->tm_month]) { + nDays[IsLeapYear(time->tm_year)][time->tm_month]) { time->tm_mday = 1; time->tm_month++; if (time->tm_month > 11) { @@ -347,8 +351,9 @@ ApplySecOffset(PRExplodedTime *time, PRInt32 secOffset) } } time->tm_wday++; - if (time->tm_wday > 6) + if (time->tm_wday > 6) { time->tm_wday = 0; + } } } @@ -360,7 +365,7 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) /* Get back to GMT */ time->tm_sec -= time->tm_params.tp_gmt_offset - + time->tm_params.tp_dst_offset; + + time->tm_params.tp_dst_offset; time->tm_params.tp_gmt_offset = 0; time->tm_params.tp_dst_offset = 0; @@ -442,8 +447,8 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) /* Recompute yday and wday */ time->tm_yday = time->tm_mday + - lastDayOfMonth[IsLeapYear(time->tm_year)][time->tm_month]; - + lastDayOfMonth[IsLeapYear(time->tm_year)][time->tm_month]; + numDays = DAYS_BETWEEN_YEARS(1970, time->tm_year) + time->tm_yday; time->tm_wday = (numDays + 4) % 7; if (time->tm_wday < 0) { @@ -455,7 +460,7 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) time->tm_params = params(time); ApplySecOffset(time, time->tm_params.tp_gmt_offset - + time->tm_params.tp_dst_offset); + + time->tm_params.tp_dst_offset); } @@ -463,7 +468,7 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) *------------------------------------------------------------------------- * * PR_LocalTimeParameters -- - * + * * returns the time parameters for the local time zone * * The following uses localtime() from the standard C library. @@ -480,7 +485,7 @@ PR_NormalizeTime(PRExplodedTime *time, PRTimeParamFn params) * In this case we could define the macro as * #define MT_safe_localtime(timer, result) \ * (localtime_r(timer, result) == 0 ? result : NULL) - * I chose to compare the return value of localtime_r with -1 so + * I chose to compare the return value of localtime_r with -1 so * that I can catch the cases where localtime_r returns a pointer * to struct tm. The macro definition above would not be able to * detect such mistakes because it is legal to compare a pointer @@ -521,7 +526,9 @@ static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result) * against NSPR threads only when the * NSPR thread system is activated. */ - if (needLock) PR_Lock(monitor); + if (needLock) { + PR_Lock(monitor); + } /* * Microsoft (all flavors) localtime() returns a NULL pointer if 'clock' @@ -538,15 +545,17 @@ static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result) * clock plus ULONG_MAX. So we also have to check for the invalid * structs returned for timezones west of Greenwich when clock == 0. */ - + tmPtr = localtime(clock); #if defined(WIN16) || defined(XP_OS2) if ( (PRInt32) *clock < 0 || - ( (PRInt32) *clock == 0 && tmPtr->tm_year != 70)) + ( (PRInt32) *clock == 0 && tmPtr->tm_year != 70)) { result = NULL; - else + } + else { *result = *tmPtr; + } #else if (tmPtr) { *result = *tmPtr; @@ -555,7 +564,9 @@ static struct tm *MT_safe_localtime(const time_t *clock, struct tm *result) } #endif /* WIN16 */ - if (needLock) PR_Unlock(monitor); + if (needLock) { + PR_Unlock(monitor); + } return result; } @@ -585,7 +596,7 @@ void _PR_CleanupTime(void) #endif } -#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS) +#if defined(XP_UNIX) || defined(XP_PC) PR_IMPLEMENT(PRTimeParameters) PR_LocalTimeParameters(const PRExplodedTime *gmt) @@ -629,10 +640,10 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt) /* GMT is 00:00:00, 2nd of Jan. */ - offset2Jan1970 = (PRInt32)localTime.tm_sec - + 60L * (PRInt32)localTime.tm_min - + 3600L * (PRInt32)localTime.tm_hour - + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L); + offset2Jan1970 = (PRInt32)localTime.tm_sec + + 60L * (PRInt32)localTime.tm_min + + 3600L * (PRInt32)localTime.tm_hour + + 86400L * (PRInt32)((PRInt32)localTime.tm_mday - 2L); isdst2Jan1970 = localTime.tm_isdst; @@ -683,7 +694,7 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt) } /* - * dayOffset is the offset between local time and GMT in + * dayOffset is the offset between local time and GMT in * the day component, which can only be -1, 0, or 1. We * use the day of the week to compute dayOffset. */ @@ -704,9 +715,9 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt) } offsetNew = (PRInt32)localTime.tm_sec - gmt->tm_sec - + 60L * ((PRInt32)localTime.tm_min - gmt->tm_min) - + 3600L * ((PRInt32)localTime.tm_hour - gmt->tm_hour) - + 86400L * (PRInt32)dayOffset; + + 60L * ((PRInt32)localTime.tm_min - gmt->tm_min) + + 3600L * ((PRInt32)localTime.tm_hour - gmt->tm_hour) + + 86400L * (PRInt32)dayOffset; if (localTime.tm_isdst <= 0) { /* DST is not in effect */ @@ -732,11 +743,11 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt) retVal.tp_dst_offset = 3600; } } - + return retVal; } -#endif /* defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS) */ +#endif /* defined(XP_UNIX) || defined(XP_PC) */ /* *------------------------------------------------------------------------ @@ -751,27 +762,28 @@ PR_LocalTimeParameters(const PRExplodedTime *gmt) /* * Returns the mday of the first sunday of the month, where * mday and wday are for a given day in the month. - * mdays start with 1 (e.g. 1..31). + * mdays start with 1 (e.g. 1..31). * wdays start with 0 and are in the range 0..6. 0 = Sunday. */ #define firstSunday(mday, wday) (((mday - wday + 7 - 1) % 7) + 1) /* - * Returns the mday for the N'th Sunday of the month, where + * Returns the mday for the N'th Sunday of the month, where * mday and wday are for a given day in the month. - * mdays start with 1 (e.g. 1..31). + * mdays start with 1 (e.g. 1..31). * wdays start with 0 and are in the range 0..6. 0 = Sunday. * N has the following values: 0 = first, 1 = second (etc), -1 = last. - * ndays is the number of days in that month, the same value as the + * ndays is the number of days in that month, the same value as the * mday of the last day of the month. */ -static PRInt32 -NthSunday(PRInt32 mday, PRInt32 wday, PRInt32 N, PRInt32 ndays) +static PRInt32 +NthSunday(PRInt32 mday, PRInt32 wday, PRInt32 N, PRInt32 ndays) { PRInt32 firstSun = firstSunday(mday, wday); - if (N < 0) + if (N < 0) { N = (ndays - firstSun) / 7; + } return firstSun + (7 * N); } @@ -825,9 +837,9 @@ PR_USPacificTimeParameters(const PRExplodedTime *gmt) ApplySecOffset(&st, retVal.tp_gmt_offset); if (st.tm_year < 2007) { /* first April Sunday - Last October Sunday */ - dst = &dstParams[0]; + dst = &dstParams[0]; } else { /* Second March Sunday - First November Sunday */ - dst = &dstParams[1]; + dst = &dstParams[1]; } /* @@ -837,38 +849,38 @@ PR_USPacificTimeParameters(const PRExplodedTime *gmt) if (st.tm_month < dst->dst_start_month) { retVal.tp_dst_offset = 0L; } else if (st.tm_month == dst->dst_start_month) { - int NthSun = NthSunday(st.tm_mday, st.tm_wday, - dst->dst_start_Nth_Sunday, - dst->dst_start_month_ndays); - if (st.tm_mday < NthSun) { /* Before starting Sunday */ - retVal.tp_dst_offset = 0L; + int NthSun = NthSunday(st.tm_mday, st.tm_wday, + dst->dst_start_Nth_Sunday, + dst->dst_start_month_ndays); + if (st.tm_mday < NthSun) { /* Before starting Sunday */ + retVal.tp_dst_offset = 0L; } else if (st.tm_mday == NthSun) { /* Starting Sunday */ - /* 01:59:59 PST -> 03:00:00 PDT */ - if (st.tm_hour < 2) { - retVal.tp_dst_offset = 0L; - } else { - retVal.tp_dst_offset = 3600L; - } - } else { /* After starting Sunday */ - retVal.tp_dst_offset = 3600L; + /* 01:59:59 PST -> 03:00:00 PDT */ + if (st.tm_hour < 2) { + retVal.tp_dst_offset = 0L; + } else { + retVal.tp_dst_offset = 3600L; + } + } else { /* After starting Sunday */ + retVal.tp_dst_offset = 3600L; } } else if (st.tm_month < dst->dst_end_month) { retVal.tp_dst_offset = 3600L; } else if (st.tm_month == dst->dst_end_month) { - int NthSun = NthSunday(st.tm_mday, st.tm_wday, - dst->dst_end_Nth_Sunday, - dst->dst_end_month_ndays); - if (st.tm_mday < NthSun) { /* Before ending Sunday */ - retVal.tp_dst_offset = 3600L; + int NthSun = NthSunday(st.tm_mday, st.tm_wday, + dst->dst_end_Nth_Sunday, + dst->dst_end_month_ndays); + if (st.tm_mday < NthSun) { /* Before ending Sunday */ + retVal.tp_dst_offset = 3600L; } else if (st.tm_mday == NthSun) { /* Ending Sunday */ - /* 01:59:59 PDT -> 01:00:00 PST */ - if (st.tm_hour < 1) { - retVal.tp_dst_offset = 3600L; - } else { - retVal.tp_dst_offset = 0L; - } - } else { /* After ending Sunday */ - retVal.tp_dst_offset = 0L; + /* 01:59:59 PDT -> 01:00:00 PST */ + if (st.tm_hour < 1) { + retVal.tp_dst_offset = 3600L; + } else { + retVal.tp_dst_offset = 0L; + } + } else { /* After ending Sunday */ + retVal.tp_dst_offset = 0L; } } else { retVal.tp_dst_offset = 0L; @@ -918,15 +930,15 @@ PR_GMTParameters(const PRExplodedTime *gmt) typedef enum { - TT_UNKNOWN, + TT_UNKNOWN, - TT_SUN, TT_MON, TT_TUE, TT_WED, TT_THU, TT_FRI, TT_SAT, + TT_SUN, TT_MON, TT_TUE, TT_WED, TT_THU, TT_FRI, TT_SAT, - TT_JAN, TT_FEB, TT_MAR, TT_APR, TT_MAY, TT_JUN, - TT_JUL, TT_AUG, TT_SEP, TT_OCT, TT_NOV, TT_DEC, + TT_JAN, TT_FEB, TT_MAR, TT_APR, TT_MAY, TT_JUN, + TT_JUL, TT_AUG, TT_SEP, TT_OCT, TT_NOV, TT_DEC, - TT_PST, TT_PDT, TT_MST, TT_MDT, TT_CST, TT_CDT, TT_EST, TT_EDT, - TT_AST, TT_NST, TT_GMT, TT_BST, TT_MET, TT_EET, TT_JST + TT_PST, TT_PDT, TT_MST, TT_MDT, TT_CST, TT_CDT, TT_EST, TT_EDT, + TT_AST, TT_NST, TT_GMT, TT_BST, TT_MET, TT_EET, TT_JST } TIME_TOKEN; /* @@ -962,716 +974,819 @@ typedef enum PR_IMPLEMENT(PRStatus) PR_ParseTimeStringToExplodedTime( - const char *string, - PRBool default_to_gmt, - PRExplodedTime *result) + const char *string, + PRBool default_to_gmt, + PRExplodedTime *result) { - TIME_TOKEN dotw = TT_UNKNOWN; - TIME_TOKEN month = TT_UNKNOWN; - TIME_TOKEN zone = TT_UNKNOWN; - int zone_offset = -1; - int dst_offset = 0; - int date = -1; - PRInt32 year = -1; - int hour = -1; - int min = -1; - int sec = -1; - struct tm *localTimeResult; - - const char *rest = string; - - int iterations = 0; - - PR_ASSERT(string && result); - if (!string || !result) return PR_FAILURE; - - while (*rest) + TIME_TOKEN dotw = TT_UNKNOWN; + TIME_TOKEN month = TT_UNKNOWN; + TIME_TOKEN zone = TT_UNKNOWN; + int zone_offset = -1; + int dst_offset = 0; + int date = -1; + PRInt32 year = -1; + int hour = -1; + int min = -1; + int sec = -1; + struct tm *localTimeResult; + + const char *rest = string; + + int iterations = 0; + + PR_ASSERT(string && result); + if (!string || !result) { + return PR_FAILURE; + } + + while (*rest) + { + + if (iterations++ > 1000) + { + return PR_FAILURE; + } + + switch (*rest) { + case 'a': case 'A': + if (month == TT_UNKNOWN && + (rest[1] == 'p' || rest[1] == 'P') && + (rest[2] == 'r' || rest[2] == 'R')) { + month = TT_APR; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_AST; + } + else if (month == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'g' || rest[2] == 'G')) { + month = TT_AUG; + } + break; + case 'b': case 'B': + if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_BST; + } + break; + case 'c': case 'C': + if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_CDT; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_CST; + } + break; + case 'd': case 'D': + if (month == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'c' || rest[2] == 'C')) { + month = TT_DEC; + } + break; + case 'e': case 'E': + if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_EDT; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_EET; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_EST; + } + break; + case 'f': case 'F': + if (month == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'b' || rest[2] == 'B')) { + month = TT_FEB; + } + else if (dotw == TT_UNKNOWN && + (rest[1] == 'r' || rest[1] == 'R') && + (rest[2] == 'i' || rest[2] == 'I')) { + dotw = TT_FRI; + } + break; + case 'g': case 'G': + if (zone == TT_UNKNOWN && + (rest[1] == 'm' || rest[1] == 'M') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_GMT; + } + break; + case 'j': case 'J': + if (month == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 'n' || rest[2] == 'N')) { + month = TT_JAN; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_JST; + } + else if (month == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'l' || rest[2] == 'L')) { + month = TT_JUL; + } + else if (month == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'n' || rest[2] == 'N')) { + month = TT_JUN; + } + break; + case 'm': case 'M': + if (month == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 'r' || rest[2] == 'R')) { + month = TT_MAR; + } + else if (month == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 'y' || rest[2] == 'Y')) { + month = TT_MAY; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_MDT; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_MET; + } + else if (dotw == TT_UNKNOWN && + (rest[1] == 'o' || rest[1] == 'O') && + (rest[2] == 'n' || rest[2] == 'N')) { + dotw = TT_MON; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_MST; + } + break; + case 'n': case 'N': + if (month == TT_UNKNOWN && + (rest[1] == 'o' || rest[1] == 'O') && + (rest[2] == 'v' || rest[2] == 'V')) { + month = TT_NOV; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_NST; + } + break; + case 'o': case 'O': + if (month == TT_UNKNOWN && + (rest[1] == 'c' || rest[1] == 'C') && + (rest[2] == 't' || rest[2] == 'T')) { + month = TT_OCT; + } + break; + case 'p': case 'P': + if (zone == TT_UNKNOWN && + (rest[1] == 'd' || rest[1] == 'D') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_PDT; + } + else if (zone == TT_UNKNOWN && + (rest[1] == 's' || rest[1] == 'S') && + (rest[2] == 't' || rest[2] == 'T')) { + zone = TT_PST; + } + break; + case 's': case 'S': + if (dotw == TT_UNKNOWN && + (rest[1] == 'a' || rest[1] == 'A') && + (rest[2] == 't' || rest[2] == 'T')) { + dotw = TT_SAT; + } + else if (month == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'p' || rest[2] == 'P')) { + month = TT_SEP; + } + else if (dotw == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'n' || rest[2] == 'N')) { + dotw = TT_SUN; + } + break; + case 't': case 'T': + if (dotw == TT_UNKNOWN && + (rest[1] == 'h' || rest[1] == 'H') && + (rest[2] == 'u' || rest[2] == 'U')) { + dotw = TT_THU; + } + else if (dotw == TT_UNKNOWN && + (rest[1] == 'u' || rest[1] == 'U') && + (rest[2] == 'e' || rest[2] == 'E')) { + dotw = TT_TUE; + } + break; + case 'u': case 'U': + if (zone == TT_UNKNOWN && + (rest[1] == 't' || rest[1] == 'T') && + !(rest[2] >= 'A' && rest[2] <= 'Z') && + !(rest[2] >= 'a' && rest[2] <= 'z')) + /* UT is the same as GMT but UTx is not. */ + { + zone = TT_GMT; + } + break; + case 'w': case 'W': + if (dotw == TT_UNKNOWN && + (rest[1] == 'e' || rest[1] == 'E') && + (rest[2] == 'd' || rest[2] == 'D')) { + dotw = TT_WED; + } + break; + + case '+': case '-': + { + const char *end; + int sign; + if (zone_offset != -1) + { + /* already got one... */ + rest++; + break; + } + if (zone != TT_UNKNOWN && zone != TT_GMT) + { + /* GMT+0300 is legal, but PST+0300 is not. */ + rest++; + break; + } - if (iterations++ > 1000) + sign = ((*rest == '+') ? 1 : -1); + rest++; /* move over sign */ + end = rest; + while (*end >= '0' && *end <= '9') { + end++; + } + if (rest == end) { /* no digits here */ + break; + } + + if ((end - rest) == 4) + /* offset in HHMM */ + zone_offset = (((((rest[0]-'0')*10) + (rest[1]-'0')) * 60) + + (((rest[2]-'0')*10) + (rest[3]-'0'))); + else if ((end - rest) == 2) + /* offset in hours */ + { + zone_offset = (((rest[0]-'0')*10) + (rest[1]-'0')) * 60; + } + else if ((end - rest) == 1) + /* offset in hours */ + { + zone_offset = (rest[0]-'0') * 60; + } + else + /* 3 or >4 */ { - return PR_FAILURE; + break; } - switch (*rest) + zone_offset *= sign; + zone = TT_GMT; + break; + } + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + { + int tmp_hour = -1; + int tmp_min = -1; + int tmp_sec = -1; + const char *end = rest + 1; + while (*end >= '0' && *end <= '9') { + end++; + } + + /* end is now the first character after a range of digits. */ + + if (*end == ':') { - case 'a': case 'A': - if (month == TT_UNKNOWN && - (rest[1] == 'p' || rest[1] == 'P') && - (rest[2] == 'r' || rest[2] == 'R')) - month = TT_APR; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_AST; - else if (month == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'g' || rest[2] == 'G')) - month = TT_AUG; - break; - case 'b': case 'B': - if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_BST; - break; - case 'c': case 'C': - if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_CDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_CST; - break; - case 'd': case 'D': - if (month == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'c' || rest[2] == 'C')) - month = TT_DEC; - break; - case 'e': case 'E': - if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_EDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_EET; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_EST; - break; - case 'f': case 'F': - if (month == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'b' || rest[2] == 'B')) - month = TT_FEB; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'r' || rest[1] == 'R') && - (rest[2] == 'i' || rest[2] == 'I')) - dotw = TT_FRI; - break; - case 'g': case 'G': - if (zone == TT_UNKNOWN && - (rest[1] == 'm' || rest[1] == 'M') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_GMT; - break; - case 'j': case 'J': - if (month == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 'n' || rest[2] == 'N')) - month = TT_JAN; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_JST; - else if (month == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'l' || rest[2] == 'L')) - month = TT_JUL; - else if (month == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'n' || rest[2] == 'N')) - month = TT_JUN; - break; - case 'm': case 'M': - if (month == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 'r' || rest[2] == 'R')) - month = TT_MAR; - else if (month == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 'y' || rest[2] == 'Y')) - month = TT_MAY; - else if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_MDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_MET; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'o' || rest[1] == 'O') && - (rest[2] == 'n' || rest[2] == 'N')) - dotw = TT_MON; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_MST; - break; - case 'n': case 'N': - if (month == TT_UNKNOWN && - (rest[1] == 'o' || rest[1] == 'O') && - (rest[2] == 'v' || rest[2] == 'V')) - month = TT_NOV; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_NST; - break; - case 'o': case 'O': - if (month == TT_UNKNOWN && - (rest[1] == 'c' || rest[1] == 'C') && - (rest[2] == 't' || rest[2] == 'T')) - month = TT_OCT; - break; - case 'p': case 'P': - if (zone == TT_UNKNOWN && - (rest[1] == 'd' || rest[1] == 'D') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_PDT; - else if (zone == TT_UNKNOWN && - (rest[1] == 's' || rest[1] == 'S') && - (rest[2] == 't' || rest[2] == 'T')) - zone = TT_PST; - break; - case 's': case 'S': - if (dotw == TT_UNKNOWN && - (rest[1] == 'a' || rest[1] == 'A') && - (rest[2] == 't' || rest[2] == 'T')) - dotw = TT_SAT; - else if (month == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'p' || rest[2] == 'P')) - month = TT_SEP; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'n' || rest[2] == 'N')) - dotw = TT_SUN; - break; - case 't': case 'T': - if (dotw == TT_UNKNOWN && - (rest[1] == 'h' || rest[1] == 'H') && - (rest[2] == 'u' || rest[2] == 'U')) - dotw = TT_THU; - else if (dotw == TT_UNKNOWN && - (rest[1] == 'u' || rest[1] == 'U') && - (rest[2] == 'e' || rest[2] == 'E')) - dotw = TT_TUE; - break; - case 'u': case 'U': - if (zone == TT_UNKNOWN && - (rest[1] == 't' || rest[1] == 'T') && - !(rest[2] >= 'A' && rest[2] <= 'Z') && - !(rest[2] >= 'a' && rest[2] <= 'z')) - /* UT is the same as GMT but UTx is not. */ - zone = TT_GMT; - break; - case 'w': case 'W': - if (dotw == TT_UNKNOWN && - (rest[1] == 'e' || rest[1] == 'E') && - (rest[2] == 'd' || rest[2] == 'D')) - dotw = TT_WED; - break; - - case '+': case '-': - { - const char *end; - int sign; - if (zone_offset != -1) - { - /* already got one... */ - rest++; - break; - } - if (zone != TT_UNKNOWN && zone != TT_GMT) - { - /* GMT+0300 is legal, but PST+0300 is not. */ - rest++; - break; - } - - sign = ((*rest == '+') ? 1 : -1); - rest++; /* move over sign */ - end = rest; - while (*end >= '0' && *end <= '9') - end++; - if (rest == end) /* no digits here */ - break; - - if ((end - rest) == 4) - /* offset in HHMM */ - zone_offset = (((((rest[0]-'0')*10) + (rest[1]-'0')) * 60) + - (((rest[2]-'0')*10) + (rest[3]-'0'))); - else if ((end - rest) == 2) - /* offset in hours */ - zone_offset = (((rest[0]-'0')*10) + (rest[1]-'0')) * 60; - else if ((end - rest) == 1) - /* offset in hours */ - zone_offset = (rest[0]-'0') * 60; - else - /* 3 or >4 */ - break; - - zone_offset *= sign; - zone = TT_GMT; + if (hour >= 0 && min >= 0) { /* already got it */ + break; + } + + /* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */ + if ((end - rest) > 2) + /* it is [0-9][0-9][0-9]+: */ + { + break; + } + if ((end - rest) == 2) + tmp_hour = ((rest[0]-'0')*10 + + (rest[1]-'0')); + else { + tmp_hour = (rest[0]-'0'); + } + + /* move over the colon, and parse minutes */ + + rest = ++end; + while (*end >= '0' && *end <= '9') { + end++; + } + + if (end == rest) + /* no digits after first colon? */ + { + break; + } + if ((end - rest) > 2) + /* it is [0-9][0-9][0-9]+: */ + { break; - } - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - { - int tmp_hour = -1; - int tmp_min = -1; - int tmp_sec = -1; - const char *end = rest + 1; - while (*end >= '0' && *end <= '9') - end++; - - /* end is now the first character after a range of digits. */ - - if (*end == ':') - { - if (hour >= 0 && min >= 0) /* already got it */ - break; - - /* We have seen "[0-9]+:", so this is probably HH:MM[:SS] */ - if ((end - rest) > 2) - /* it is [0-9][0-9][0-9]+: */ - break; - if ((end - rest) == 2) - tmp_hour = ((rest[0]-'0')*10 + - (rest[1]-'0')); - else - tmp_hour = (rest[0]-'0'); - - /* move over the colon, and parse minutes */ - - rest = ++end; - while (*end >= '0' && *end <= '9') - end++; - - if (end == rest) - /* no digits after first colon? */ - break; - if ((end - rest) > 2) - /* it is [0-9][0-9][0-9]+: */ - break; - if ((end - rest) == 2) - tmp_min = ((rest[0]-'0')*10 + - (rest[1]-'0')); - else - tmp_min = (rest[0]-'0'); - - /* now go for seconds */ - rest = end; - if (*rest == ':') - rest++; - end = rest; - while (*end >= '0' && *end <= '9') - end++; - - if (end == rest) - /* no digits after second colon - that's ok. */ - ; - else if ((end - rest) > 2) - /* it is [0-9][0-9][0-9]+: */ - break; - if ((end - rest) == 2) - tmp_sec = ((rest[0]-'0')*10 + - (rest[1]-'0')); - else - tmp_sec = (rest[0]-'0'); - - /* If we made it here, we've parsed hour and min, - and possibly sec, so it worked as a unit. */ - - /* skip over whitespace and see if there's an AM or PM - directly following the time. - */ - if (tmp_hour <= 12) - { - const char *s = end; - while (*s && (*s == ' ' || *s == '\t')) - s++; - if ((s[0] == 'p' || s[0] == 'P') && - (s[1] == 'm' || s[1] == 'M')) - /* 10:05pm == 22:05, and 12:05pm == 12:05 */ - tmp_hour = (tmp_hour == 12 ? 12 : tmp_hour + 12); - else if (tmp_hour == 12 && - (s[0] == 'a' || s[0] == 'A') && - (s[1] == 'm' || s[1] == 'M')) - /* 12:05am == 00:05 */ - tmp_hour = 0; - } - - hour = tmp_hour; - min = tmp_min; - sec = tmp_sec; - rest = end; - break; - } - if ((*end == '/' || *end == '-') && - end[1] >= '0' && end[1] <= '9') - { - /* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95 - or even 95-06-05... - #### But it doesn't handle 1995-06-22. - */ - int n1, n2, n3; - const char *s; - - if (month != TT_UNKNOWN) - /* if we saw a month name, this can't be. */ - break; - - s = rest; - - n1 = (*s++ - '0'); /* first 1 or 2 digits */ - if (*s >= '0' && *s <= '9') - n1 = n1*10 + (*s++ - '0'); - - if (*s != '/' && *s != '-') /* slash */ - break; - s++; - - if (*s < '0' || *s > '9') /* second 1 or 2 digits */ - break; - n2 = (*s++ - '0'); - if (*s >= '0' && *s <= '9') - n2 = n2*10 + (*s++ - '0'); - - if (*s != '/' && *s != '-') /* slash */ - break; - s++; - - if (*s < '0' || *s > '9') /* third 1, 2, 4, or 5 digits */ - break; - n3 = (*s++ - '0'); - if (*s >= '0' && *s <= '9') - n3 = n3*10 + (*s++ - '0'); - - if (*s >= '0' && *s <= '9') /* optional digits 3, 4, and 5 */ - { - n3 = n3*10 + (*s++ - '0'); - if (*s < '0' || *s > '9') - break; - n3 = n3*10 + (*s++ - '0'); - if (*s >= '0' && *s <= '9') - n3 = n3*10 + (*s++ - '0'); - } - - if ((*s >= '0' && *s <= '9') || /* followed by non-alphanum */ - (*s >= 'A' && *s <= 'Z') || - (*s >= 'a' && *s <= 'z')) - break; - - /* Ok, we parsed three 1-2 digit numbers, with / or - - between them. Now decide what the hell they are - (DD/MM/YY or MM/DD/YY or YY/MM/DD.) - */ - - if (n1 > 31 || n1 == 0) /* must be YY/MM/DD */ - { - if (n2 > 12) break; - if (n3 > 31) break; - year = n1; - if (year < 70) - year += 2000; - else if (year < 100) - year += 1900; - month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); - date = n3; - rest = s; - break; - } - - if (n1 > 12 && n2 > 12) /* illegal */ - { - rest = s; - break; - } - - if (n3 < 70) - n3 += 2000; - else if (n3 < 100) - n3 += 1900; - - if (n1 > 12) /* must be DD/MM/YY */ - { - date = n1; - month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); - year = n3; - } - else /* assume MM/DD/YY */ - { - /* #### In the ambiguous case, should we consult the - locale to find out the local default? */ - month = (TIME_TOKEN)(n1 + ((int)TT_JAN) - 1); - date = n2; - year = n3; - } - rest = s; - } - else if ((*end >= 'A' && *end <= 'Z') || - (*end >= 'a' && *end <= 'z')) - /* Digits followed by non-punctuation - what's that? */ - ; - else if ((end - rest) == 5) /* five digits is a year */ - year = (year < 0 - ? ((rest[0]-'0')*10000L + - (rest[1]-'0')*1000L + - (rest[2]-'0')*100L + - (rest[3]-'0')*10L + - (rest[4]-'0')) - : year); - else if ((end - rest) == 4) /* four digits is a year */ - year = (year < 0 - ? ((rest[0]-'0')*1000L + - (rest[1]-'0')*100L + - (rest[2]-'0')*10L + - (rest[3]-'0')) - : year); - else if ((end - rest) == 2) /* two digits - date or year */ - { - int n = ((rest[0]-'0')*10 + - (rest[1]-'0')); - /* If we don't have a date (day of the month) and we see a number - less than 32, then assume that is the date. - - Otherwise, if we have a date and not a year, assume this is the - year. If it is less than 70, then assume it refers to the 21st - century. If it is two digits (>= 70), assume it refers to this - century. Otherwise, assume it refers to an unambiguous year. - - The world will surely end soon. - */ - if (date < 0 && n < 32) - date = n; - else if (year < 0) - { - if (n < 70) - year = 2000 + n; - else if (n < 100) - year = 1900 + n; - else - year = n; - } - /* else what the hell is this. */ - } - else if ((end - rest) == 1) /* one digit - date */ - date = (date < 0 ? (rest[0]-'0') : date); - /* else, three or more than five digits - what's that? */ + } + if ((end - rest) == 2) + tmp_min = ((rest[0]-'0')*10 + + (rest[1]-'0')); + else { + tmp_min = (rest[0]-'0'); + } + /* now go for seconds */ + rest = end; + if (*rest == ':') { + rest++; + } + end = rest; + while (*end >= '0' && *end <= '9') { + end++; + } + + if (end == rest) + /* no digits after second colon - that's ok. */ + ; + else if ((end - rest) > 2) + /* it is [0-9][0-9][0-9]+: */ + { break; - } + } + if ((end - rest) == 2) + tmp_sec = ((rest[0]-'0')*10 + + (rest[1]-'0')); + else { + tmp_sec = (rest[0]-'0'); + } + + /* If we made it here, we've parsed hour and min, + and possibly sec, so it worked as a unit. */ + + /* skip over whitespace and see if there's an AM or PM + directly following the time. + */ + if (tmp_hour <= 12) + { + const char *s = end; + while (*s && (*s == ' ' || *s == '\t')) { + s++; + } + if ((s[0] == 'p' || s[0] == 'P') && + (s[1] == 'm' || s[1] == 'M')) + /* 10:05pm == 22:05, and 12:05pm == 12:05 */ + { + tmp_hour = (tmp_hour == 12 ? 12 : tmp_hour + 12); + } + else if (tmp_hour == 12 && + (s[0] == 'a' || s[0] == 'A') && + (s[1] == 'm' || s[1] == 'M')) + /* 12:05am == 00:05 */ + { + tmp_hour = 0; + } + } + + hour = tmp_hour; + min = tmp_min; + sec = tmp_sec; + rest = end; + break; } + if ((*end == '/' || *end == '-') && + end[1] >= '0' && end[1] <= '9') + { + /* Perhaps this is 6/16/95, 16/6/95, 6-16-95, or 16-6-95 + or even 95-06-05... + #### But it doesn't handle 1995-06-22. + */ + int n1, n2, n3; + const char *s; + + if (month != TT_UNKNOWN) + /* if we saw a month name, this can't be. */ + { + break; + } + + s = rest; + + n1 = (*s++ - '0'); /* first 1 or 2 digits */ + if (*s >= '0' && *s <= '9') { + n1 = n1*10 + (*s++ - '0'); + } + + if (*s != '/' && *s != '-') { /* slash */ + break; + } + s++; + + if (*s < '0' || *s > '9') { /* second 1 or 2 digits */ + break; + } + n2 = (*s++ - '0'); + if (*s >= '0' && *s <= '9') { + n2 = n2*10 + (*s++ - '0'); + } + + if (*s != '/' && *s != '-') { /* slash */ + break; + } + s++; + + if (*s < '0' || *s > '9') { /* third 1, 2, 4, or 5 digits */ + break; + } + n3 = (*s++ - '0'); + if (*s >= '0' && *s <= '9') { + n3 = n3*10 + (*s++ - '0'); + } + + if (*s >= '0' && *s <= '9') /* optional digits 3, 4, and 5 */ + { + n3 = n3*10 + (*s++ - '0'); + if (*s < '0' || *s > '9') { + break; + } + n3 = n3*10 + (*s++ - '0'); + if (*s >= '0' && *s <= '9') { + n3 = n3*10 + (*s++ - '0'); + } + } + + if ((*s >= '0' && *s <= '9') || /* followed by non-alphanum */ + (*s >= 'A' && *s <= 'Z') || + (*s >= 'a' && *s <= 'z')) { + break; + } + + /* Ok, we parsed three 1-2 digit numbers, with / or - + between them. Now decide what the hell they are + (DD/MM/YY or MM/DD/YY or YY/MM/DD.) + */ + + if (n1 > 31 || n1 == 0) /* must be YY/MM/DD */ + { + if (n2 > 12) { + break; + } + if (n3 > 31) { + break; + } + year = n1; + if (year < 70) { + year += 2000; + } + else if (year < 100) { + year += 1900; + } + month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); + date = n3; + rest = s; + break; + } + + if (n1 > 12 && n2 > 12) /* illegal */ + { + rest = s; + break; + } - /* Skip to the end of this token, whether we parsed it or not. - Tokens are delimited by whitespace, or ,;-/ - But explicitly not :+-. - */ - while (*rest && - *rest != ' ' && *rest != '\t' && - *rest != ',' && *rest != ';' && - *rest != '-' && *rest != '+' && - *rest != '/' && - *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']') - rest++; - /* skip over uninteresting chars. */ - SKIP_MORE: - while (*rest && - (*rest == ' ' || *rest == '\t' || - *rest == ',' || *rest == ';' || *rest == '/' || - *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']')) - rest++; - - /* "-" is ignored at the beginning of a token if we have not yet - parsed a year (e.g., the second "-" in "30-AUG-1966"), or if - the character after the dash is not a digit. */ - if (*rest == '-' && ((rest > string && - isalpha((unsigned char)rest[-1]) && year < 0) || - rest[1] < '0' || rest[1] > '9')) + if (n3 < 70) { + n3 += 2000; + } + else if (n3 < 100) { + n3 += 1900; + } + + if (n1 > 12) /* must be DD/MM/YY */ + { + date = n1; + month = (TIME_TOKEN)(n2 + ((int)TT_JAN) - 1); + year = n3; + } + else /* assume MM/DD/YY */ + { + /* #### In the ambiguous case, should we consult the + locale to find out the local default? */ + month = (TIME_TOKEN)(n1 + ((int)TT_JAN) - 1); + date = n2; + year = n3; + } + rest = s; + } + else if ((*end >= 'A' && *end <= 'Z') || + (*end >= 'a' && *end <= 'z')) + /* Digits followed by non-punctuation - what's that? */ + ; + else if ((end - rest) == 5) /* five digits is a year */ + year = (year < 0 + ? ((rest[0]-'0')*10000L + + (rest[1]-'0')*1000L + + (rest[2]-'0')*100L + + (rest[3]-'0')*10L + + (rest[4]-'0')) + : year); + else if ((end - rest) == 4) /* four digits is a year */ + year = (year < 0 + ? ((rest[0]-'0')*1000L + + (rest[1]-'0')*100L + + (rest[2]-'0')*10L + + (rest[3]-'0')) + : year); + else if ((end - rest) == 2) /* two digits - date or year */ { - rest++; - goto SKIP_MORE; + int n = ((rest[0]-'0')*10 + + (rest[1]-'0')); + /* If we don't have a date (day of the month) and we see a number + less than 32, then assume that is the date. + + Otherwise, if we have a date and not a year, assume this is the + year. If it is less than 70, then assume it refers to the 21st + century. If it is two digits (>= 70), assume it refers to this + century. Otherwise, assume it refers to an unambiguous year. + + The world will surely end soon. + */ + if (date < 0 && n < 32) { + date = n; + } + else if (year < 0) + { + if (n < 70) { + year = 2000 + n; + } + else if (n < 100) { + year = 1900 + n; + } + else { + year = n; + } + } + /* else what the hell is this. */ } + else if ((end - rest) == 1) { /* one digit - date */ + date = (date < 0 ? (rest[0]-'0') : date); + } + /* else, three or more than five digits - what's that? */ + + break; + } + } + /* Skip to the end of this token, whether we parsed it or not. + Tokens are delimited by whitespace, or ,;-/ + But explicitly not :+-. + */ + while (*rest && + *rest != ' ' && *rest != '\t' && + *rest != ',' && *rest != ';' && + *rest != '-' && *rest != '+' && + *rest != '/' && + *rest != '(' && *rest != ')' && *rest != '[' && *rest != ']') { + rest++; + } + /* skip over uninteresting chars. */ +SKIP_MORE: + while (*rest && + (*rest == ' ' || *rest == '\t' || + *rest == ',' || *rest == ';' || *rest == '/' || + *rest == '(' || *rest == ')' || *rest == '[' || *rest == ']')) { + rest++; } - if (zone != TT_UNKNOWN && zone_offset == -1) + /* "-" is ignored at the beginning of a token if we have not yet + parsed a year (e.g., the second "-" in "30-AUG-1966"), or if + the character after the dash is not a digit. */ + if (*rest == '-' && ((rest > string && + isalpha((unsigned char)rest[-1]) && year < 0) || + rest[1] < '0' || rest[1] > '9')) { - switch (zone) - { - case TT_PST: zone_offset = -8 * 60; break; - case TT_PDT: zone_offset = -8 * 60; dst_offset = 1 * 60; break; - case TT_MST: zone_offset = -7 * 60; break; - case TT_MDT: zone_offset = -7 * 60; dst_offset = 1 * 60; break; - case TT_CST: zone_offset = -6 * 60; break; - case TT_CDT: zone_offset = -6 * 60; dst_offset = 1 * 60; break; - case TT_EST: zone_offset = -5 * 60; break; - case TT_EDT: zone_offset = -5 * 60; dst_offset = 1 * 60; break; - case TT_AST: zone_offset = -4 * 60; break; - case TT_NST: zone_offset = -3 * 60 - 30; break; - case TT_GMT: zone_offset = 0 * 60; break; - case TT_BST: zone_offset = 0 * 60; dst_offset = 1 * 60; break; - case TT_MET: zone_offset = 1 * 60; break; - case TT_EET: zone_offset = 2 * 60; break; - case TT_JST: zone_offset = 9 * 60; break; - default: - PR_ASSERT (0); - break; - } + rest++; + goto SKIP_MORE; + } + + } + + if (zone != TT_UNKNOWN && zone_offset == -1) + { + switch (zone) + { + case TT_PST: zone_offset = -8 * 60; break; + case TT_PDT: zone_offset = -8 * 60; dst_offset = 1 * 60; break; + case TT_MST: zone_offset = -7 * 60; break; + case TT_MDT: zone_offset = -7 * 60; dst_offset = 1 * 60; break; + case TT_CST: zone_offset = -6 * 60; break; + case TT_CDT: zone_offset = -6 * 60; dst_offset = 1 * 60; break; + case TT_EST: zone_offset = -5 * 60; break; + case TT_EDT: zone_offset = -5 * 60; dst_offset = 1 * 60; break; + case TT_AST: zone_offset = -4 * 60; break; + case TT_NST: zone_offset = -3 * 60 - 30; break; + case TT_GMT: zone_offset = 0 * 60; break; + case TT_BST: zone_offset = 0 * 60; dst_offset = 1 * 60; break; + case TT_MET: zone_offset = 1 * 60; break; + case TT_EET: zone_offset = 2 * 60; break; + case TT_JST: zone_offset = 9 * 60; break; + default: + PR_ASSERT (0); + break; } + } - /* If we didn't find a year, month, or day-of-the-month, we can't - possibly parse this, and in fact, mktime() will do something random - (I'm seeing it return "Tue Feb 5 06:28:16 2036", which is no doubt - a numerologically significant date... */ - if (month == TT_UNKNOWN || date == -1 || year == -1 || year > PR_INT16_MAX) - return PR_FAILURE; + /* If we didn't find a year, month, or day-of-the-month, we can't + possibly parse this, and in fact, mktime() will do something random + (I'm seeing it return "Tue Feb 5 06:28:16 2036", which is no doubt + a numerologically significant date... */ + if (month == TT_UNKNOWN || date == -1 || year == -1 || year > PR_INT16_MAX) { + return PR_FAILURE; + } - memset(result, 0, sizeof(*result)); - if (sec != -1) + memset(result, 0, sizeof(*result)); + if (sec != -1) { result->tm_sec = sec; - if (min != -1) + } + if (min != -1) { result->tm_min = min; - if (hour != -1) + } + if (hour != -1) { result->tm_hour = hour; - if (date != -1) + } + if (date != -1) { result->tm_mday = date; - if (month != TT_UNKNOWN) + } + if (month != TT_UNKNOWN) { result->tm_month = (((int)month) - ((int)TT_JAN)); - if (year != -1) + } + if (year != -1) { result->tm_year = year; - if (dotw != TT_UNKNOWN) + } + if (dotw != TT_UNKNOWN) { result->tm_wday = (((int)dotw) - ((int)TT_SUN)); - /* - * Mainly to compute wday and yday, but normalized time is also required - * by the check below that works around a Visual C++ 2005 mktime problem. - */ - PR_NormalizeTime(result, PR_GMTParameters); - /* The remaining work is to set the gmt and dst offsets in tm_params. */ - - if (zone == TT_UNKNOWN && default_to_gmt) - { - /* No zone was specified, so pretend the zone was GMT. */ - zone = TT_GMT; - zone_offset = 0; - } + } + /* + * Mainly to compute wday and yday, but normalized time is also required + * by the check below that works around a Visual C++ 2005 mktime problem. + */ + PR_NormalizeTime(result, PR_GMTParameters); + /* The remaining work is to set the gmt and dst offsets in tm_params. */ + + if (zone == TT_UNKNOWN && default_to_gmt) + { + /* No zone was specified, so pretend the zone was GMT. */ + zone = TT_GMT; + zone_offset = 0; + } - if (zone_offset == -1) - { - /* no zone was specified, and we're to assume that everything - is local. */ - struct tm localTime; - time_t secs; + if (zone_offset == -1) + { + /* no zone was specified, and we're to assume that everything + is local. */ + struct tm localTime; + time_t secs; - PR_ASSERT(result->tm_month > -1 && - result->tm_mday > 0 && - result->tm_hour > -1 && - result->tm_min > -1 && - result->tm_sec > -1); + PR_ASSERT(result->tm_month > -1 && + result->tm_mday > 0 && + result->tm_hour > -1 && + result->tm_min > -1 && + result->tm_sec > -1); - /* - * To obtain time_t from a tm structure representing the local - * time, we call mktime(). However, we need to see if we are - * on 1-Jan-1970 or before. If we are, we can't call mktime() - * because mktime() will crash on win16. In that case, we - * calculate zone_offset based on the zone offset at - * 00:00:00, 2 Jan 1970 GMT, and subtract zone_offset from the - * date we are parsing to transform the date to GMT. We also - * do so if mktime() returns (time_t) -1 (time out of range). - */ - - /* month, day, hours, mins and secs are always non-negative - so we dont need to worry about them. */ - if(result->tm_year >= 1970) - { - PRInt64 usec_per_sec; - - localTime.tm_sec = result->tm_sec; - localTime.tm_min = result->tm_min; - localTime.tm_hour = result->tm_hour; - localTime.tm_mday = result->tm_mday; - localTime.tm_mon = result->tm_month; - localTime.tm_year = result->tm_year - 1900; - /* Set this to -1 to tell mktime "I don't care". If you set - it to 0 or 1, you are making assertions about whether the - date you are handing it is in daylight savings mode or not; - and if you're wrong, it will "fix" it for you. */ - localTime.tm_isdst = -1; + /* + * To obtain time_t from a tm structure representing the local + * time, we call mktime(). However, we need to see if we are + * on 1-Jan-1970 or before. If we are, we can't call mktime() + * because mktime() will crash on win16. In that case, we + * calculate zone_offset based on the zone offset at + * 00:00:00, 2 Jan 1970 GMT, and subtract zone_offset from the + * date we are parsing to transform the date to GMT. We also + * do so if mktime() returns (time_t) -1 (time out of range). + */ + + /* month, day, hours, mins and secs are always non-negative + so we dont need to worry about them. */ + if(result->tm_year >= 1970) + { + PRInt64 usec_per_sec; + + localTime.tm_sec = result->tm_sec; + localTime.tm_min = result->tm_min; + localTime.tm_hour = result->tm_hour; + localTime.tm_mday = result->tm_mday; + localTime.tm_mon = result->tm_month; + localTime.tm_year = result->tm_year - 1900; + /* Set this to -1 to tell mktime "I don't care". If you set + it to 0 or 1, you are making assertions about whether the + date you are handing it is in daylight savings mode or not; + and if you're wrong, it will "fix" it for you. */ + localTime.tm_isdst = -1; #if _MSC_VER == 1400 /* 1400 = Visual C++ 2005 (8.0) */ - /* - * mktime will return (time_t) -1 if the input is a date - * after 23:59:59, December 31, 3000, US Pacific Time (not - * UTC as documented): - * http://msdn.microsoft.com/en-us/library/d1y53h2a(VS.80).aspx - * But if the year is 3001, mktime also invokes the invalid - * parameter handler, causing the application to crash. This - * problem has been reported in - * http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=266036. - * We avoid this crash by not calling mktime if the date is - * out of range. To use a simple test that works in any time - * zone, we consider year 3000 out of range as well. (See - * bug 480740.) - */ - if (result->tm_year >= 3000) { - /* Emulate what mktime would have done. */ - errno = EINVAL; - secs = (time_t) -1; - } else { - secs = mktime(&localTime); - } + /* + * mktime will return (time_t) -1 if the input is a date + * after 23:59:59, December 31, 3000, US Pacific Time (not + * UTC as documented): + * http://msdn.microsoft.com/en-us/library/d1y53h2a(VS.80).aspx + * But if the year is 3001, mktime also invokes the invalid + * parameter handler, causing the application to crash. This + * problem has been reported in + * http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=266036. + * We avoid this crash by not calling mktime if the date is + * out of range. To use a simple test that works in any time + * zone, we consider year 3000 out of range as well. (See + * bug 480740.) + */ + if (result->tm_year >= 3000) { + /* Emulate what mktime would have done. */ + errno = EINVAL; + secs = (time_t) -1; + } else { + secs = mktime(&localTime); + } #else - secs = mktime(&localTime); + secs = mktime(&localTime); #endif - if (secs != (time_t) -1) - { - PRTime usecs64; - LL_I2L(usecs64, secs); - LL_I2L(usec_per_sec, PR_USEC_PER_SEC); - LL_MUL(usecs64, usecs64, usec_per_sec); - PR_ExplodeTime(usecs64, PR_LocalTimeParameters, result); - return PR_SUCCESS; - } - } - - /* So mktime() can't handle this case. We assume the - zone_offset for the date we are parsing is the same as - the zone offset on 00:00:00 2 Jan 1970 GMT. */ - secs = 86400; - localTimeResult = MT_safe_localtime(&secs, &localTime); - PR_ASSERT(localTimeResult != NULL); - if (localTimeResult == NULL) { - return PR_FAILURE; - } - zone_offset = localTime.tm_min - + 60 * localTime.tm_hour - + 1440 * (localTime.tm_mday - 2); + if (secs != (time_t) -1) + { + PRTime usecs64; + LL_I2L(usecs64, secs); + LL_I2L(usec_per_sec, PR_USEC_PER_SEC); + LL_MUL(usecs64, usecs64, usec_per_sec); + PR_ExplodeTime(usecs64, PR_LocalTimeParameters, result); + return PR_SUCCESS; + } } - result->tm_params.tp_gmt_offset = zone_offset * 60; - result->tm_params.tp_dst_offset = dst_offset * 60; + /* So mktime() can't handle this case. We assume the + zone_offset for the date we are parsing is the same as + the zone offset on 00:00:00 2 Jan 1970 GMT. */ + secs = 86400; + localTimeResult = MT_safe_localtime(&secs, &localTime); + PR_ASSERT(localTimeResult != NULL); + if (localTimeResult == NULL) { + return PR_FAILURE; + } + zone_offset = localTime.tm_min + + 60 * localTime.tm_hour + + 1440 * (localTime.tm_mday - 2); + } - return PR_SUCCESS; + result->tm_params.tp_gmt_offset = zone_offset * 60; + result->tm_params.tp_dst_offset = dst_offset * 60; + + return PR_SUCCESS; } PR_IMPLEMENT(PRStatus) PR_ParseTimeString( - const char *string, - PRBool default_to_gmt, - PRTime *result) + const char *string, + PRBool default_to_gmt, + PRTime *result) { - PRExplodedTime tm; - PRStatus rv; + PRExplodedTime tm; + PRStatus rv; - rv = PR_ParseTimeStringToExplodedTime(string, - default_to_gmt, - &tm); - if (rv != PR_SUCCESS) + rv = PR_ParseTimeStringToExplodedTime(string, + default_to_gmt, + &tm); + if (rv != PR_SUCCESS) { return rv; + } - *result = PR_ImplodeTime(&tm); + *result = PR_ImplodeTime(&tm); - return PR_SUCCESS; + return PR_SUCCESS; } /* @@ -1720,9 +1835,9 @@ PR_FormatTime(char *buf, int buflen, const char *fmt, * additional fields: tm_zone and tm_gmtoff. */ -#if (__GLIBC__ >= 2) || defined(XP_BEOS) \ - || defined(NETBSD) || defined(OPENBSD) || defined(FREEBSD) \ - || defined(DARWIN) || defined(SYMBIAN) || defined(ANDROID) +#if (__GLIBC__ >= 2) || defined(NETBSD) \ + || defined(OPENBSD) || defined(FREEBSD) \ + || defined(DARWIN) || defined(ANDROID) a.tm_zone = NULL; a.tm_gmtoff = time->tm_params.tp_gmt_offset + time->tm_params.tp_dst_offset; @@ -1750,22 +1865,22 @@ PR_FormatTime(char *buf, int buflen, const char *fmt, static const char* abbrevDays[] = { - "Sun","Mon","Tue","Wed","Thu","Fri","Sat" + "Sun","Mon","Tue","Wed","Thu","Fri","Sat" }; static const char* days[] = { - "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" + "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" }; static const char* abbrevMonths[] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; static const char* months[] = -{ +{ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; @@ -1813,7 +1928,7 @@ while(0) /* Needed by PR_FormatTimeUSEnglish() */ static unsigned int pr_WeekOfYear(const PRExplodedTime* time, - unsigned int firstDayOfWeek); + unsigned int firstDayOfWeek); /*********************************************************************************** @@ -1824,169 +1939,169 @@ static unsigned int pr_WeekOfYear(const PRExplodedTime* time, * needed to write things like MIME headers which must always be in US English. * **********************************************************************************/ - + PR_IMPLEMENT(PRUint32) PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize, const char* format, const PRExplodedTime* time ) { - char* bufPtr = buf; - const char* fmtPtr; - char tmpBuf[ 40 ]; - const int tmpBufSize = sizeof( tmpBuf ); - - - for( fmtPtr=format; *fmtPtr != '\0'; fmtPtr++ ) - { - if( *fmtPtr != '%' ) - { - ADDCHAR( bufPtr, bufSize, *fmtPtr ); - } - else - { - switch( *(++fmtPtr) ) - { - case '%': - /* escaped '%' character */ - ADDCHAR( bufPtr, bufSize, '%' ); - break; - - case 'a': - /* abbreviated weekday name */ - ADDSTR( bufPtr, bufSize, abbrevDays[ time->tm_wday ] ); - break; - - case 'A': - /* full weekday name */ - ADDSTR( bufPtr, bufSize, days[ time->tm_wday ] ); - break; - - case 'b': - /* abbreviated month name */ - ADDSTR( bufPtr, bufSize, abbrevMonths[ time->tm_month ] ); - break; - - case 'B': - /* full month name */ - ADDSTR(bufPtr, bufSize, months[ time->tm_month ] ); - break; - - case 'c': - /* Date and time. */ - PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%a %b %d %H:%M:%S %Y", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'd': - /* day of month ( 01 - 31 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_mday ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'H': - /* hour ( 00 - 23 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_hour ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'I': - /* hour ( 01 - 12 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld", - (time->tm_hour%12) ? time->tm_hour%12 : (PRInt32) 12 ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'j': - /* day number of year ( 001 - 366 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.3d",time->tm_yday + 1); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'm': - /* month number ( 01 - 12 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_month+1); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'M': - /* minute ( 00 - 59 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_min ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'p': - /* locale's equivalent of either AM or PM */ - ADDSTR( bufPtr, bufSize, (time->tm_hour<12)?"AM":"PM" ); - break; - - case 'S': - /* seconds ( 00 - 61 ), allows for leap seconds */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_sec ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'U': - /* week number of year ( 00 - 53 ), Sunday is the first day of week 1 */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 0 ) ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'w': - /* weekday number ( 0 - 6 ), Sunday = 0 */ - PR_snprintf(tmpBuf,tmpBufSize,"%d",time->tm_wday ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'W': - /* Week number of year ( 00 - 53 ), Monday is the first day of week 1 */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 1 ) ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'x': - /* Date representation */ - PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%m/%d/%y", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'X': - /* Time representation. */ - PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%H:%M:%S", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'y': - /* year within century ( 00 - 99 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.2d",time->tm_year % 100 ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'Y': - /* year as ccyy ( for example 1986 ) */ - PR_snprintf(tmpBuf,tmpBufSize,"%.4d",time->tm_year ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; - - case 'Z': - /* Time zone name or no characters if no time zone exists. - * Since time zone name is supposed to be independant of locale, we - * defer to PR_FormatTime() for this option. - */ - PR_FormatTime( tmpBuf, tmpBufSize, "%Z", time ); - ADDSTR( bufPtr, bufSize, tmpBuf ); - break; + char* bufPtr = buf; + const char* fmtPtr; + char tmpBuf[ 40 ]; + const int tmpBufSize = sizeof( tmpBuf ); - default: - /* Unknown format. Simply copy format into output buffer. */ - ADDCHAR( bufPtr, bufSize, '%' ); + + for( fmtPtr=format; *fmtPtr != '\0'; fmtPtr++ ) + { + if( *fmtPtr != '%' ) + { ADDCHAR( bufPtr, bufSize, *fmtPtr ); - break; - - } - } - } - - ADDCHAR( bufPtr, bufSize, '\0' ); - return (PRUint32)(bufPtr - buf - 1); + } + else + { + switch( *(++fmtPtr) ) + { + case '%': + /* escaped '%' character */ + ADDCHAR( bufPtr, bufSize, '%' ); + break; + + case 'a': + /* abbreviated weekday name */ + ADDSTR( bufPtr, bufSize, abbrevDays[ time->tm_wday ] ); + break; + + case 'A': + /* full weekday name */ + ADDSTR( bufPtr, bufSize, days[ time->tm_wday ] ); + break; + + case 'b': + /* abbreviated month name */ + ADDSTR( bufPtr, bufSize, abbrevMonths[ time->tm_month ] ); + break; + + case 'B': + /* full month name */ + ADDSTR(bufPtr, bufSize, months[ time->tm_month ] ); + break; + + case 'c': + /* Date and time. */ + PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%a %b %d %H:%M:%S %Y", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'd': + /* day of month ( 01 - 31 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_mday ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'H': + /* hour ( 00 - 23 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_hour ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'I': + /* hour ( 01 - 12 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld", + (time->tm_hour%12) ? time->tm_hour%12 : (PRInt32) 12 ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'j': + /* day number of year ( 001 - 366 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.3d",time->tm_yday + 1); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'm': + /* month number ( 01 - 12 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_month+1); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'M': + /* minute ( 00 - 59 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_min ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'p': + /* locale's equivalent of either AM or PM */ + ADDSTR( bufPtr, bufSize, (time->tm_hour<12)?"AM":"PM" ); + break; + + case 'S': + /* seconds ( 00 - 61 ), allows for leap seconds */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2ld",time->tm_sec ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'U': + /* week number of year ( 00 - 53 ), Sunday is the first day of week 1 */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 0 ) ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'w': + /* weekday number ( 0 - 6 ), Sunday = 0 */ + PR_snprintf(tmpBuf,tmpBufSize,"%d",time->tm_wday ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'W': + /* Week number of year ( 00 - 53 ), Monday is the first day of week 1 */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2d", pr_WeekOfYear( time, 1 ) ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'x': + /* Date representation */ + PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%m/%d/%y", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'X': + /* Time representation. */ + PR_FormatTimeUSEnglish( tmpBuf, tmpBufSize, "%H:%M:%S", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'y': + /* year within century ( 00 - 99 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.2d",time->tm_year % 100 ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'Y': + /* year as ccyy ( for example 1986 ) */ + PR_snprintf(tmpBuf,tmpBufSize,"%.4d",time->tm_year ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + case 'Z': + /* Time zone name or no characters if no time zone exists. + * Since time zone name is supposed to be independant of locale, we + * defer to PR_FormatTime() for this option. + */ + PR_FormatTime( tmpBuf, tmpBufSize, "%Z", time ); + ADDSTR( bufPtr, bufSize, tmpBuf ); + break; + + default: + /* Unknown format. Simply copy format into output buffer. */ + ADDCHAR( bufPtr, bufSize, '%' ); + ADDCHAR( bufPtr, bufSize, *fmtPtr ); + break; + + } + } + } + + ADDCHAR( bufPtr, bufSize, '\0' ); + return (PRUint32)(bufPtr - buf - 1); } @@ -1997,38 +2112,39 @@ PR_FormatTimeUSEnglish( char* buf, PRUint32 bufSize, * Returns the week number of the year (0-53) for the given time. firstDayOfWeek * is the day on which the week is considered to start (0=Sun, 1=Mon, ...). * Week 1 starts the first time firstDayOfWeek occurs in the year. In other words, - * a partial week at the start of the year is considered week 0. + * a partial week at the start of the year is considered week 0. * **********************************************************************************/ static unsigned int pr_WeekOfYear(const PRExplodedTime* time, unsigned int firstDayOfWeek) { - int dayOfWeek; - int dayOfYear; - - /* Get the day of the year for the given time then adjust it to represent the - * first day of the week containing the given time. - */ - dayOfWeek = time->tm_wday - firstDayOfWeek; - if (dayOfWeek < 0) - dayOfWeek += 7; - - dayOfYear = time->tm_yday - dayOfWeek; - - if( dayOfYear <= 0 ) - { - /* If dayOfYear is <= 0, it is in the first partial week of the year. */ - return 0; - } - - /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there - * are any days left over ( dayOfYear % 7 ). Because we are only counting to - * the first day of the week containing the given time, rather than to the - * actual day representing the given time, any days in week 0 will be "absorbed" - * as extra days in the given week. - */ - return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 ); + int dayOfWeek; + int dayOfYear; + + /* Get the day of the year for the given time then adjust it to represent the + * first day of the week containing the given time. + */ + dayOfWeek = time->tm_wday - firstDayOfWeek; + if (dayOfWeek < 0) { + dayOfWeek += 7; + } + + dayOfYear = time->tm_yday - dayOfWeek; + + if( dayOfYear <= 0 ) + { + /* If dayOfYear is <= 0, it is in the first partial week of the year. */ + return 0; + } + + /* Count the number of full weeks ( dayOfYear / 7 ) then add a week if there + * are any days left over ( dayOfYear % 7 ). Because we are only counting to + * the first day of the week containing the given time, rather than to the + * actual day representing the given time, any days in week 0 will be "absorbed" + * as extra days in the given week. + */ + return (dayOfYear / 7) + ( (dayOfYear % 7) == 0 ? 0 : 1 ); } diff --git a/nsprpub/pr/src/misc/prtpool.c b/nsprpub/pr/src/misc/prtpool.c index c2cc9c803..69f588ef6 100644 --- a/nsprpub/pr/src/misc/prtpool.c +++ b/nsprpub/pr/src/misc/prtpool.c @@ -7,8 +7,8 @@ /* * Thread pools - * Thread pools create and manage threads to provide support for - * scheduling jobs onto one or more threads. + * Thread pools create and manage threads to provide support for + * scheduling jobs onto one or more threads. * */ #ifdef OPT_WINNT @@ -19,32 +19,32 @@ * worker thread */ typedef struct wthread { - PRCList links; - PRThread *thread; + PRCList links; + PRThread *thread; } wthread; /* * queue of timer jobs */ typedef struct timer_jobq { - PRCList list; - PRLock *lock; - PRCondVar *cv; - PRInt32 cnt; - PRCList wthreads; + PRCList list; + PRLock *lock; + PRCondVar *cv; + PRInt32 cnt; + PRCList wthreads; } timer_jobq; /* * queue of jobs */ typedef struct tp_jobq { - PRCList list; - PRInt32 cnt; - PRLock *lock; - PRCondVar *cv; - PRCList wthreads; + PRCList list; + PRInt32 cnt; + PRLock *lock; + PRCondVar *cv; + PRCList wthreads; #ifdef OPT_WINNT - HANDLE nt_completion_port; + HANDLE nt_completion_port; #endif } tp_jobq; @@ -52,62 +52,62 @@ typedef struct tp_jobq { * queue of IO jobs */ typedef struct io_jobq { - PRCList list; - PRPollDesc *pollfds; - PRInt32 npollfds; - PRJob **polljobs; - PRLock *lock; - PRInt32 cnt; - PRFileDesc *notify_fd; - PRCList wthreads; + PRCList list; + PRPollDesc *pollfds; + PRInt32 npollfds; + PRJob **polljobs; + PRLock *lock; + PRInt32 cnt; + PRFileDesc *notify_fd; + PRCList wthreads; } io_jobq; /* * Threadpool */ struct PRThreadPool { - PRInt32 init_threads; - PRInt32 max_threads; - PRInt32 current_threads; - PRInt32 idle_threads; - PRUint32 stacksize; - tp_jobq jobq; - io_jobq ioq; - timer_jobq timerq; - PRLock *join_lock; /* used with jobp->join_cv */ - PRCondVar *shutdown_cv; - PRBool shutdown; + PRInt32 init_threads; + PRInt32 max_threads; + PRInt32 current_threads; + PRInt32 idle_threads; + PRUint32 stacksize; + tp_jobq jobq; + io_jobq ioq; + timer_jobq timerq; + PRLock *join_lock; /* used with jobp->join_cv */ + PRCondVar *shutdown_cv; + PRBool shutdown; }; typedef enum io_op_type - { JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type; +{ JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type; #ifdef OPT_WINNT typedef struct NT_notifier { - OVERLAPPED overlapped; /* must be first */ - PRJob *jobp; + OVERLAPPED overlapped; /* must be first */ + PRJob *jobp; } NT_notifier; #endif struct PRJob { - PRCList links; /* for linking jobs */ - PRBool on_ioq; /* job on ioq */ - PRBool on_timerq; /* job on timerq */ - PRJobFn job_func; - void *job_arg; - PRCondVar *join_cv; - PRBool join_wait; /* == PR_TRUE, when waiting to join */ - PRCondVar *cancel_cv; /* for cancelling IO jobs */ - PRBool cancel_io; /* for cancelling IO jobs */ - PRThreadPool *tpool; /* back pointer to thread pool */ - PRJobIoDesc *iod; - io_op_type io_op; - PRInt16 io_poll_flags; - PRNetAddr *netaddr; - PRIntervalTime timeout; /* relative value */ - PRIntervalTime absolute; + PRCList links; /* for linking jobs */ + PRBool on_ioq; /* job on ioq */ + PRBool on_timerq; /* job on timerq */ + PRJobFn job_func; + void *job_arg; + PRCondVar *join_cv; + PRBool join_wait; /* == PR_TRUE, when waiting to join */ + PRCondVar *cancel_cv; /* for cancelling IO jobs */ + PRBool cancel_io; /* for cancelling IO jobs */ + PRThreadPool *tpool; /* back pointer to thread pool */ + PRJobIoDesc *iod; + io_op_type io_op; + PRInt16 io_poll_flags; + PRNetAddr *netaddr; + PRIntervalTime timeout; /* relative value */ + PRIntervalTime absolute; #ifdef OPT_WINNT - NT_notifier nt_notifier; + NT_notifier nt_notifier; #endif }; @@ -119,22 +119,22 @@ struct PRJob { #define JOINABLE_JOB(_jobp) (NULL != (_jobp)->join_cv) -#define JOIN_NOTIFY(_jobp) \ - PR_BEGIN_MACRO \ - PR_Lock(_jobp->tpool->join_lock); \ - _jobp->join_wait = PR_FALSE; \ - PR_NotifyCondVar(_jobp->join_cv); \ - PR_Unlock(_jobp->tpool->join_lock); \ - PR_END_MACRO - -#define CANCEL_IO_JOB(jobp) \ - PR_BEGIN_MACRO \ - jobp->cancel_io = PR_FALSE; \ - jobp->on_ioq = PR_FALSE; \ - PR_REMOVE_AND_INIT_LINK(&jobp->links); \ - tp->ioq.cnt--; \ - PR_NotifyCondVar(jobp->cancel_cv); \ - PR_END_MACRO +#define JOIN_NOTIFY(_jobp) \ + PR_BEGIN_MACRO \ + PR_Lock(_jobp->tpool->join_lock); \ + _jobp->join_wait = PR_FALSE; \ + PR_NotifyCondVar(_jobp->join_cv); \ + PR_Unlock(_jobp->tpool->join_lock); \ + PR_END_MACRO + +#define CANCEL_IO_JOB(jobp) \ + PR_BEGIN_MACRO \ + jobp->cancel_io = PR_FALSE; \ + jobp->on_ioq = PR_FALSE; \ + PR_REMOVE_AND_INIT_LINK(&jobp->links); \ + tp->ioq.cnt--; \ + PR_NotifyCondVar(jobp->cancel_cv); \ + PR_END_MACRO static void delete_job(PRJob *jobp); static PRThreadPool * alloc_threadpool(void); @@ -145,10 +145,10 @@ static void notify_timerq(PRThreadPool *tp); /* * locks are acquired in the following order * - * tp->ioq.lock,tp->timerq.lock - * | - * V - * tp->jobq->lock + * tp->ioq.lock,tp->timerq.lock + * | + * V + * tp->jobq->lock */ /* @@ -156,65 +156,66 @@ static void notify_timerq(PRThreadPool *tp); */ static void wstart(void *arg) { -PRThreadPool *tp = (PRThreadPool *) arg; -PRCList *head; - - /* - * execute jobs until shutdown - */ - while (!tp->shutdown) { - PRJob *jobp; + PRThreadPool *tp = (PRThreadPool *) arg; + PRCList *head; + + /* + * execute jobs until shutdown + */ + while (!tp->shutdown) { + PRJob *jobp; #ifdef OPT_WINNT - BOOL rv; - DWORD unused, shutdown; - LPOVERLAPPED olp; - - PR_Lock(tp->jobq.lock); - tp->idle_threads++; - PR_Unlock(tp->jobq.lock); - rv = GetQueuedCompletionStatus(tp->jobq.nt_completion_port, - &unused, &shutdown, &olp, INFINITE); - - PR_ASSERT(rv); - if (shutdown) - break; - jobp = ((NT_notifier *) olp)->jobp; - PR_Lock(tp->jobq.lock); - tp->idle_threads--; - tp->jobq.cnt--; - PR_Unlock(tp->jobq.lock); + BOOL rv; + DWORD unused, shutdown; + LPOVERLAPPED olp; + + PR_Lock(tp->jobq.lock); + tp->idle_threads++; + PR_Unlock(tp->jobq.lock); + rv = GetQueuedCompletionStatus(tp->jobq.nt_completion_port, + &unused, &shutdown, &olp, INFINITE); + + PR_ASSERT(rv); + if (shutdown) { + break; + } + jobp = ((NT_notifier *) olp)->jobp; + PR_Lock(tp->jobq.lock); + tp->idle_threads--; + tp->jobq.cnt--; + PR_Unlock(tp->jobq.lock); #else - PR_Lock(tp->jobq.lock); - while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) { - tp->idle_threads++; - PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT); - tp->idle_threads--; - } - if (tp->shutdown) { - PR_Unlock(tp->jobq.lock); - break; - } - head = PR_LIST_HEAD(&tp->jobq.list); - /* - * remove job from queue - */ - PR_REMOVE_AND_INIT_LINK(head); - tp->jobq.cnt--; - jobp = JOB_LINKS_PTR(head); - PR_Unlock(tp->jobq.lock); + PR_Lock(tp->jobq.lock); + while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) { + tp->idle_threads++; + PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT); + tp->idle_threads--; + } + if (tp->shutdown) { + PR_Unlock(tp->jobq.lock); + break; + } + head = PR_LIST_HEAD(&tp->jobq.list); + /* + * remove job from queue + */ + PR_REMOVE_AND_INIT_LINK(head); + tp->jobq.cnt--; + jobp = JOB_LINKS_PTR(head); + PR_Unlock(tp->jobq.lock); #endif - jobp->job_func(jobp->job_arg); - if (!JOINABLE_JOB(jobp)) { - delete_job(jobp); - } else { - JOIN_NOTIFY(jobp); - } - } - PR_Lock(tp->jobq.lock); - tp->current_threads--; - PR_Unlock(tp->jobq.lock); + jobp->job_func(jobp->job_arg); + if (!JOINABLE_JOB(jobp)) { + delete_job(jobp); + } else { + JOIN_NOTIFY(jobp); + } + } + PR_Lock(tp->jobq.lock); + tp->current_threads--; + PR_Unlock(tp->jobq.lock); } /* @@ -223,52 +224,52 @@ PRCList *head; static void add_to_jobq(PRThreadPool *tp, PRJob *jobp) { - /* - * add to jobq - */ + /* + * add to jobq + */ #ifdef OPT_WINNT - PR_Lock(tp->jobq.lock); - tp->jobq.cnt++; - PR_Unlock(tp->jobq.lock); - /* - * notify worker thread(s) - */ - PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0, - FALSE, &jobp->nt_notifier.overlapped); + PR_Lock(tp->jobq.lock); + tp->jobq.cnt++; + PR_Unlock(tp->jobq.lock); + /* + * notify worker thread(s) + */ + PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0, + FALSE, &jobp->nt_notifier.overlapped); #else - PR_Lock(tp->jobq.lock); - PR_APPEND_LINK(&jobp->links,&tp->jobq.list); - tp->jobq.cnt++; - if ((tp->idle_threads < tp->jobq.cnt) && - (tp->current_threads < tp->max_threads)) { - wthread *wthrp; - /* - * increment thread count and unlock the jobq lock - */ - tp->current_threads++; - PR_Unlock(tp->jobq.lock); - /* create new worker thread */ - wthrp = PR_NEWZAP(wthread); - if (wthrp) { - wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize); - if (NULL == wthrp->thread) { - PR_DELETE(wthrp); /* this sets wthrp to NULL */ - } - } - PR_Lock(tp->jobq.lock); - if (NULL == wthrp) { - tp->current_threads--; - } else { - PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); - } - } - /* - * wakeup a worker thread - */ - PR_NotifyCondVar(tp->jobq.cv); - PR_Unlock(tp->jobq.lock); + PR_Lock(tp->jobq.lock); + PR_APPEND_LINK(&jobp->links,&tp->jobq.list); + tp->jobq.cnt++; + if ((tp->idle_threads < tp->jobq.cnt) && + (tp->current_threads < tp->max_threads)) { + wthread *wthrp; + /* + * increment thread count and unlock the jobq lock + */ + tp->current_threads++; + PR_Unlock(tp->jobq.lock); + /* create new worker thread */ + wthrp = PR_NEWZAP(wthread); + if (wthrp) { + wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize); + if (NULL == wthrp->thread) { + PR_DELETE(wthrp); /* this sets wthrp to NULL */ + } + } + PR_Lock(tp->jobq.lock); + if (NULL == wthrp) { + tp->current_threads--; + } else { + PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); + } + } + /* + * wakeup a worker thread + */ + PR_NotifyCondVar(tp->jobq.cv); + PR_Unlock(tp->jobq.lock); #endif } @@ -277,207 +278,220 @@ add_to_jobq(PRThreadPool *tp, PRJob *jobp) */ static void io_wstart(void *arg) { -PRThreadPool *tp = (PRThreadPool *) arg; -int pollfd_cnt, pollfds_used; -int rv; -PRCList *qp, *nextqp; -PRPollDesc *pollfds = NULL; -PRJob **polljobs = NULL; -int poll_timeout; -PRIntervalTime now; - - /* - * scan io_jobq - * construct poll list - * call PR_Poll - * for all fds, for which poll returns true, move the job to - * jobq and wakeup worker thread. - */ - while (!tp->shutdown) { - PRJob *jobp; - - pollfd_cnt = tp->ioq.cnt + 10; - if (pollfd_cnt > tp->ioq.npollfds) { - - /* - * re-allocate pollfd array if the current one is not large - * enough - */ - if (NULL != tp->ioq.pollfds) - PR_Free(tp->ioq.pollfds); - tp->ioq.pollfds = (PRPollDesc *) PR_Malloc(pollfd_cnt * - (sizeof(PRPollDesc) + sizeof(PRJob *))); - PR_ASSERT(NULL != tp->ioq.pollfds); - /* - * array of pollfds - */ - pollfds = tp->ioq.pollfds; - tp->ioq.polljobs = (PRJob **) (&tp->ioq.pollfds[pollfd_cnt]); - /* - * parallel array of jobs - */ - polljobs = tp->ioq.polljobs; - tp->ioq.npollfds = pollfd_cnt; - } - - pollfds_used = 0; - /* - * add the notify fd; used for unblocking io thread(s) - */ - pollfds[pollfds_used].fd = tp->ioq.notify_fd; - pollfds[pollfds_used].in_flags = PR_POLL_READ; - pollfds[pollfds_used].out_flags = 0; - polljobs[pollfds_used] = NULL; - pollfds_used++; - /* - * fill in the pollfd array - */ - PR_Lock(tp->ioq.lock); - for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { - nextqp = qp->next; - jobp = JOB_LINKS_PTR(qp); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - continue; - } - if (pollfds_used == (pollfd_cnt)) - break; - pollfds[pollfds_used].fd = jobp->iod->socket; - pollfds[pollfds_used].in_flags = jobp->io_poll_flags; - pollfds[pollfds_used].out_flags = 0; - polljobs[pollfds_used] = jobp; - - pollfds_used++; - } - if (!PR_CLIST_IS_EMPTY(&tp->ioq.list)) { - qp = tp->ioq.list.next; - jobp = JOB_LINKS_PTR(qp); - if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) - poll_timeout = PR_INTERVAL_NO_TIMEOUT; - else if (PR_INTERVAL_NO_WAIT == jobp->timeout) - poll_timeout = PR_INTERVAL_NO_WAIT; - else { - poll_timeout = jobp->absolute - PR_IntervalNow(); - if (poll_timeout <= 0) /* already timed out */ - poll_timeout = PR_INTERVAL_NO_WAIT; - } - } else { - poll_timeout = PR_INTERVAL_NO_TIMEOUT; - } - PR_Unlock(tp->ioq.lock); - - /* - * XXXX - * should retry if more jobs have been added to the queue? - * - */ - PR_ASSERT(pollfds_used <= pollfd_cnt); - rv = PR_Poll(tp->ioq.pollfds, pollfds_used, poll_timeout); - - if (tp->shutdown) { - break; - } - - if (rv > 0) { - /* - * at least one io event is set - */ - PRStatus rval_status; - PRInt32 index; - - PR_ASSERT(pollfds[0].fd == tp->ioq.notify_fd); - /* - * reset the pollable event, if notified - */ - if (pollfds[0].out_flags & PR_POLL_READ) { - rval_status = PR_WaitForPollableEvent(tp->ioq.notify_fd); - PR_ASSERT(PR_SUCCESS == rval_status); - } - - for(index = 1; index < (pollfds_used); index++) { + PRThreadPool *tp = (PRThreadPool *) arg; + int pollfd_cnt, pollfds_used; + int rv; + PRCList *qp, *nextqp; + PRPollDesc *pollfds = NULL; + PRJob **polljobs = NULL; + int poll_timeout; + PRIntervalTime now; + + /* + * scan io_jobq + * construct poll list + * call PR_Poll + * for all fds, for which poll returns true, move the job to + * jobq and wakeup worker thread. + */ + while (!tp->shutdown) { + PRJob *jobp; + + pollfd_cnt = tp->ioq.cnt + 10; + if (pollfd_cnt > tp->ioq.npollfds) { + + /* + * re-allocate pollfd array if the current one is not large + * enough + */ + if (NULL != tp->ioq.pollfds) { + PR_Free(tp->ioq.pollfds); + } + tp->ioq.pollfds = (PRPollDesc *) PR_Malloc(pollfd_cnt * + (sizeof(PRPollDesc) + sizeof(PRJob *))); + PR_ASSERT(NULL != tp->ioq.pollfds); + /* + * array of pollfds + */ + pollfds = tp->ioq.pollfds; + tp->ioq.polljobs = (PRJob **) (&tp->ioq.pollfds[pollfd_cnt]); + /* + * parallel array of jobs + */ + polljobs = tp->ioq.polljobs; + tp->ioq.npollfds = pollfd_cnt; + } + + pollfds_used = 0; + /* + * add the notify fd; used for unblocking io thread(s) + */ + pollfds[pollfds_used].fd = tp->ioq.notify_fd; + pollfds[pollfds_used].in_flags = PR_POLL_READ; + pollfds[pollfds_used].out_flags = 0; + polljobs[pollfds_used] = NULL; + pollfds_used++; + /* + * fill in the pollfd array + */ + PR_Lock(tp->ioq.lock); + for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { + nextqp = qp->next; + jobp = JOB_LINKS_PTR(qp); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + continue; + } + if (pollfds_used == (pollfd_cnt)) { + break; + } + pollfds[pollfds_used].fd = jobp->iod->socket; + pollfds[pollfds_used].in_flags = jobp->io_poll_flags; + pollfds[pollfds_used].out_flags = 0; + polljobs[pollfds_used] = jobp; + + pollfds_used++; + } + if (!PR_CLIST_IS_EMPTY(&tp->ioq.list)) { + qp = tp->ioq.list.next; + jobp = JOB_LINKS_PTR(qp); + if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) { + poll_timeout = PR_INTERVAL_NO_TIMEOUT; + } + else if (PR_INTERVAL_NO_WAIT == jobp->timeout) { + poll_timeout = PR_INTERVAL_NO_WAIT; + } + else { + poll_timeout = jobp->absolute - PR_IntervalNow(); + if (poll_timeout <= 0) { /* already timed out */ + poll_timeout = PR_INTERVAL_NO_WAIT; + } + } + } else { + poll_timeout = PR_INTERVAL_NO_TIMEOUT; + } + PR_Unlock(tp->ioq.lock); + + /* + * XXXX + * should retry if more jobs have been added to the queue? + * + */ + PR_ASSERT(pollfds_used <= pollfd_cnt); + rv = PR_Poll(tp->ioq.pollfds, pollfds_used, poll_timeout); + + if (tp->shutdown) { + break; + } + + if (rv > 0) { + /* + * at least one io event is set + */ + PRStatus rval_status; + PRInt32 index; + + PR_ASSERT(pollfds[0].fd == tp->ioq.notify_fd); + /* + * reset the pollable event, if notified + */ + if (pollfds[0].out_flags & PR_POLL_READ) { + rval_status = PR_WaitForPollableEvent(tp->ioq.notify_fd); + PR_ASSERT(PR_SUCCESS == rval_status); + } + + for(index = 1; index < (pollfds_used); index++) { PRInt16 events = pollfds[index].in_flags; - PRInt16 revents = pollfds[index].out_flags; - jobp = polljobs[index]; + PRInt16 revents = pollfds[index].out_flags; + jobp = polljobs[index]; if ((revents & PR_POLL_NVAL) || /* busted in all cases */ - (revents & PR_POLL_ERR) || - ((events & PR_POLL_WRITE) && - (revents & PR_POLL_HUP))) { /* write op & hup */ - PR_Lock(tp->ioq.lock); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - PR_Unlock(tp->ioq.lock); - continue; - } - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->ioq.cnt--; - jobp->on_ioq = PR_FALSE; - PR_Unlock(tp->ioq.lock); - - /* set error */ - if (PR_POLL_NVAL & revents) - jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR; - else if (PR_POLL_HUP & revents) - jobp->iod->error = PR_CONNECT_RESET_ERROR; - else - jobp->iod->error = PR_IO_ERROR; - - /* - * add to jobq - */ - add_to_jobq(tp, jobp); - } else if (revents) { - /* - * add to jobq - */ - PR_Lock(tp->ioq.lock); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - PR_Unlock(tp->ioq.lock); - continue; - } - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->ioq.cnt--; - jobp->on_ioq = PR_FALSE; - PR_Unlock(tp->ioq.lock); - - if (jobp->io_op == JOB_IO_CONNECT) { - if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS) - jobp->iod->error = 0; - else - jobp->iod->error = PR_GetError(); - } else - jobp->iod->error = 0; - - add_to_jobq(tp, jobp); - } - } - } - /* - * timeout processing - */ - now = PR_IntervalNow(); - PR_Lock(tp->ioq.lock); - for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { - nextqp = qp->next; - jobp = JOB_LINKS_PTR(qp); - if (jobp->cancel_io) { - CANCEL_IO_JOB(jobp); - continue; - } - if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) - break; - if ((PR_INTERVAL_NO_WAIT != jobp->timeout) && - ((PRInt32)(jobp->absolute - now) > 0)) - break; - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->ioq.cnt--; - jobp->on_ioq = PR_FALSE; - jobp->iod->error = PR_IO_TIMEOUT_ERROR; - add_to_jobq(tp, jobp); - } - PR_Unlock(tp->ioq.lock); - } + (revents & PR_POLL_ERR) || + ((events & PR_POLL_WRITE) && + (revents & PR_POLL_HUP))) { /* write op & hup */ + PR_Lock(tp->ioq.lock); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + PR_Unlock(tp->ioq.lock); + continue; + } + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->ioq.cnt--; + jobp->on_ioq = PR_FALSE; + PR_Unlock(tp->ioq.lock); + + /* set error */ + if (PR_POLL_NVAL & revents) { + jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR; + } + else if (PR_POLL_HUP & revents) { + jobp->iod->error = PR_CONNECT_RESET_ERROR; + } + else { + jobp->iod->error = PR_IO_ERROR; + } + + /* + * add to jobq + */ + add_to_jobq(tp, jobp); + } else if (revents) { + /* + * add to jobq + */ + PR_Lock(tp->ioq.lock); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + PR_Unlock(tp->ioq.lock); + continue; + } + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->ioq.cnt--; + jobp->on_ioq = PR_FALSE; + PR_Unlock(tp->ioq.lock); + + if (jobp->io_op == JOB_IO_CONNECT) { + if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS) { + jobp->iod->error = 0; + } + else { + jobp->iod->error = PR_GetError(); + } + } else { + jobp->iod->error = 0; + } + + add_to_jobq(tp, jobp); + } + } + } + /* + * timeout processing + */ + now = PR_IntervalNow(); + PR_Lock(tp->ioq.lock); + for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = nextqp) { + nextqp = qp->next; + jobp = JOB_LINKS_PTR(qp); + if (jobp->cancel_io) { + CANCEL_IO_JOB(jobp); + continue; + } + if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout) { + break; + } + if ((PR_INTERVAL_NO_WAIT != jobp->timeout) && + ((PRInt32)(jobp->absolute - now) > 0)) { + break; + } + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->ioq.cnt--; + jobp->on_ioq = PR_FALSE; + jobp->iod->error = PR_IO_TIMEOUT_ERROR; + add_to_jobq(tp, jobp); + } + PR_Unlock(tp->ioq.lock); + } } /* @@ -485,391 +499,419 @@ PRIntervalTime now; */ static void timer_wstart(void *arg) { -PRThreadPool *tp = (PRThreadPool *) arg; -PRCList *qp; -PRIntervalTime timeout; -PRIntervalTime now; - - /* - * call PR_WaitCondVar with minimum value of all timeouts - */ - while (!tp->shutdown) { - PRJob *jobp; - - PR_Lock(tp->timerq.lock); - if (PR_CLIST_IS_EMPTY(&tp->timerq.list)) { - timeout = PR_INTERVAL_NO_TIMEOUT; - } else { - PRCList *qp; - - qp = tp->timerq.list.next; - jobp = JOB_LINKS_PTR(qp); - - timeout = jobp->absolute - PR_IntervalNow(); - if (timeout <= 0) - timeout = PR_INTERVAL_NO_WAIT; /* already timed out */ - } - if (PR_INTERVAL_NO_WAIT != timeout) - PR_WaitCondVar(tp->timerq.cv, timeout); - if (tp->shutdown) { - PR_Unlock(tp->timerq.lock); - break; - } - /* - * move expired-timer jobs to jobq - */ - now = PR_IntervalNow(); - while (!PR_CLIST_IS_EMPTY(&tp->timerq.list)) { - qp = tp->timerq.list.next; - jobp = JOB_LINKS_PTR(qp); - - if ((PRInt32)(jobp->absolute - now) > 0) { - break; - } - /* - * job timed out - */ - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->timerq.cnt--; - jobp->on_timerq = PR_FALSE; - add_to_jobq(tp, jobp); - } - PR_Unlock(tp->timerq.lock); - } + PRThreadPool *tp = (PRThreadPool *) arg; + PRCList *qp; + PRIntervalTime timeout; + PRIntervalTime now; + + /* + * call PR_WaitCondVar with minimum value of all timeouts + */ + while (!tp->shutdown) { + PRJob *jobp; + + PR_Lock(tp->timerq.lock); + if (PR_CLIST_IS_EMPTY(&tp->timerq.list)) { + timeout = PR_INTERVAL_NO_TIMEOUT; + } else { + PRCList *qp; + + qp = tp->timerq.list.next; + jobp = JOB_LINKS_PTR(qp); + + timeout = jobp->absolute - PR_IntervalNow(); + if (timeout <= 0) { + timeout = PR_INTERVAL_NO_WAIT; /* already timed out */ + } + } + if (PR_INTERVAL_NO_WAIT != timeout) { + PR_WaitCondVar(tp->timerq.cv, timeout); + } + if (tp->shutdown) { + PR_Unlock(tp->timerq.lock); + break; + } + /* + * move expired-timer jobs to jobq + */ + now = PR_IntervalNow(); + while (!PR_CLIST_IS_EMPTY(&tp->timerq.list)) { + qp = tp->timerq.list.next; + jobp = JOB_LINKS_PTR(qp); + + if ((PRInt32)(jobp->absolute - now) > 0) { + break; + } + /* + * job timed out + */ + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->timerq.cnt--; + jobp->on_timerq = PR_FALSE; + add_to_jobq(tp, jobp); + } + PR_Unlock(tp->timerq.lock); + } } static void delete_threadpool(PRThreadPool *tp) { - if (NULL != tp) { - if (NULL != tp->shutdown_cv) - PR_DestroyCondVar(tp->shutdown_cv); - if (NULL != tp->jobq.cv) - PR_DestroyCondVar(tp->jobq.cv); - if (NULL != tp->jobq.lock) - PR_DestroyLock(tp->jobq.lock); - if (NULL != tp->join_lock) - PR_DestroyLock(tp->join_lock); + if (NULL != tp) { + if (NULL != tp->shutdown_cv) { + PR_DestroyCondVar(tp->shutdown_cv); + } + if (NULL != tp->jobq.cv) { + PR_DestroyCondVar(tp->jobq.cv); + } + if (NULL != tp->jobq.lock) { + PR_DestroyLock(tp->jobq.lock); + } + if (NULL != tp->join_lock) { + PR_DestroyLock(tp->join_lock); + } #ifdef OPT_WINNT - if (NULL != tp->jobq.nt_completion_port) - CloseHandle(tp->jobq.nt_completion_port); + if (NULL != tp->jobq.nt_completion_port) { + CloseHandle(tp->jobq.nt_completion_port); + } #endif - /* Timer queue */ - if (NULL != tp->timerq.cv) - PR_DestroyCondVar(tp->timerq.cv); - if (NULL != tp->timerq.lock) - PR_DestroyLock(tp->timerq.lock); - - if (NULL != tp->ioq.lock) - PR_DestroyLock(tp->ioq.lock); - if (NULL != tp->ioq.pollfds) - PR_Free(tp->ioq.pollfds); - if (NULL != tp->ioq.notify_fd) - PR_DestroyPollableEvent(tp->ioq.notify_fd); - PR_Free(tp); - } - return; + /* Timer queue */ + if (NULL != tp->timerq.cv) { + PR_DestroyCondVar(tp->timerq.cv); + } + if (NULL != tp->timerq.lock) { + PR_DestroyLock(tp->timerq.lock); + } + + if (NULL != tp->ioq.lock) { + PR_DestroyLock(tp->ioq.lock); + } + if (NULL != tp->ioq.pollfds) { + PR_Free(tp->ioq.pollfds); + } + if (NULL != tp->ioq.notify_fd) { + PR_DestroyPollableEvent(tp->ioq.notify_fd); + } + PR_Free(tp); + } + return; } static PRThreadPool * alloc_threadpool(void) { -PRThreadPool *tp; - - tp = (PRThreadPool *) PR_CALLOC(sizeof(*tp)); - if (NULL == tp) - goto failed; - tp->jobq.lock = PR_NewLock(); - if (NULL == tp->jobq.lock) - goto failed; - tp->jobq.cv = PR_NewCondVar(tp->jobq.lock); - if (NULL == tp->jobq.cv) - goto failed; - tp->join_lock = PR_NewLock(); - if (NULL == tp->join_lock) - goto failed; + PRThreadPool *tp; + + tp = (PRThreadPool *) PR_CALLOC(sizeof(*tp)); + if (NULL == tp) { + goto failed; + } + tp->jobq.lock = PR_NewLock(); + if (NULL == tp->jobq.lock) { + goto failed; + } + tp->jobq.cv = PR_NewCondVar(tp->jobq.lock); + if (NULL == tp->jobq.cv) { + goto failed; + } + tp->join_lock = PR_NewLock(); + if (NULL == tp->join_lock) { + goto failed; + } #ifdef OPT_WINNT - tp->jobq.nt_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, - NULL, 0, 0); - if (NULL == tp->jobq.nt_completion_port) - goto failed; + tp->jobq.nt_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, + NULL, 0, 0); + if (NULL == tp->jobq.nt_completion_port) { + goto failed; + } #endif - tp->ioq.lock = PR_NewLock(); - if (NULL == tp->ioq.lock) - goto failed; - - /* Timer queue */ - - tp->timerq.lock = PR_NewLock(); - if (NULL == tp->timerq.lock) - goto failed; - tp->timerq.cv = PR_NewCondVar(tp->timerq.lock); - if (NULL == tp->timerq.cv) - goto failed; - - tp->shutdown_cv = PR_NewCondVar(tp->jobq.lock); - if (NULL == tp->shutdown_cv) - goto failed; - tp->ioq.notify_fd = PR_NewPollableEvent(); - if (NULL == tp->ioq.notify_fd) - goto failed; - return tp; + tp->ioq.lock = PR_NewLock(); + if (NULL == tp->ioq.lock) { + goto failed; + } + + /* Timer queue */ + + tp->timerq.lock = PR_NewLock(); + if (NULL == tp->timerq.lock) { + goto failed; + } + tp->timerq.cv = PR_NewCondVar(tp->timerq.lock); + if (NULL == tp->timerq.cv) { + goto failed; + } + + tp->shutdown_cv = PR_NewCondVar(tp->jobq.lock); + if (NULL == tp->shutdown_cv) { + goto failed; + } + tp->ioq.notify_fd = PR_NewPollableEvent(); + if (NULL == tp->ioq.notify_fd) { + goto failed; + } + return tp; failed: - delete_threadpool(tp); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; + delete_threadpool(tp); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; } /* Create thread pool */ PR_IMPLEMENT(PRThreadPool *) PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads, - PRUint32 stacksize) + PRUint32 stacksize) { -PRThreadPool *tp; -PRThread *thr; -int i; -wthread *wthrp; - - tp = alloc_threadpool(); - if (NULL == tp) - return NULL; - - tp->init_threads = initial_threads; - tp->max_threads = max_threads; - tp->stacksize = stacksize; - PR_INIT_CLIST(&tp->jobq.list); - PR_INIT_CLIST(&tp->ioq.list); - PR_INIT_CLIST(&tp->timerq.list); - PR_INIT_CLIST(&tp->jobq.wthreads); - PR_INIT_CLIST(&tp->ioq.wthreads); - PR_INIT_CLIST(&tp->timerq.wthreads); - tp->shutdown = PR_FALSE; - - PR_Lock(tp->jobq.lock); - for(i=0; i < initial_threads; ++i) { - - thr = PR_CreateThread(PR_USER_THREAD, wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,stacksize); - PR_ASSERT(thr); - wthrp = PR_NEWZAP(wthread); - PR_ASSERT(wthrp); - wthrp->thread = thr; - PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); - } - tp->current_threads = initial_threads; - - thr = PR_CreateThread(PR_USER_THREAD, io_wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); - PR_ASSERT(thr); - wthrp = PR_NEWZAP(wthread); - PR_ASSERT(wthrp); - wthrp->thread = thr; - PR_APPEND_LINK(&wthrp->links, &tp->ioq.wthreads); - - thr = PR_CreateThread(PR_USER_THREAD, timer_wstart, - tp, PR_PRIORITY_NORMAL, - PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); - PR_ASSERT(thr); - wthrp = PR_NEWZAP(wthread); - PR_ASSERT(wthrp); - wthrp->thread = thr; - PR_APPEND_LINK(&wthrp->links, &tp->timerq.wthreads); - - PR_Unlock(tp->jobq.lock); - return tp; + PRThreadPool *tp; + PRThread *thr; + int i; + wthread *wthrp; + + tp = alloc_threadpool(); + if (NULL == tp) { + return NULL; + } + + tp->init_threads = initial_threads; + tp->max_threads = max_threads; + tp->stacksize = stacksize; + PR_INIT_CLIST(&tp->jobq.list); + PR_INIT_CLIST(&tp->ioq.list); + PR_INIT_CLIST(&tp->timerq.list); + PR_INIT_CLIST(&tp->jobq.wthreads); + PR_INIT_CLIST(&tp->ioq.wthreads); + PR_INIT_CLIST(&tp->timerq.wthreads); + tp->shutdown = PR_FALSE; + + PR_Lock(tp->jobq.lock); + for(i=0; i < initial_threads; ++i) { + + thr = PR_CreateThread(PR_USER_THREAD, wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,stacksize); + PR_ASSERT(thr); + wthrp = PR_NEWZAP(wthread); + PR_ASSERT(wthrp); + wthrp->thread = thr; + PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads); + } + tp->current_threads = initial_threads; + + thr = PR_CreateThread(PR_USER_THREAD, io_wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); + PR_ASSERT(thr); + wthrp = PR_NEWZAP(wthread); + PR_ASSERT(wthrp); + wthrp->thread = thr; + PR_APPEND_LINK(&wthrp->links, &tp->ioq.wthreads); + + thr = PR_CreateThread(PR_USER_THREAD, timer_wstart, + tp, PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,stacksize); + PR_ASSERT(thr); + wthrp = PR_NEWZAP(wthread); + PR_ASSERT(wthrp); + wthrp->thread = thr; + PR_APPEND_LINK(&wthrp->links, &tp->timerq.wthreads); + + PR_Unlock(tp->jobq.lock); + return tp; } static void delete_job(PRJob *jobp) { - if (NULL != jobp) { - if (NULL != jobp->join_cv) { - PR_DestroyCondVar(jobp->join_cv); - jobp->join_cv = NULL; - } - if (NULL != jobp->cancel_cv) { - PR_DestroyCondVar(jobp->cancel_cv); - jobp->cancel_cv = NULL; - } - PR_DELETE(jobp); - } + if (NULL != jobp) { + if (NULL != jobp->join_cv) { + PR_DestroyCondVar(jobp->join_cv); + jobp->join_cv = NULL; + } + if (NULL != jobp->cancel_cv) { + PR_DestroyCondVar(jobp->cancel_cv); + jobp->cancel_cv = NULL; + } + PR_DELETE(jobp); + } } static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp) { - PRJob *jobp; - - jobp = PR_NEWZAP(PRJob); - if (NULL == jobp) - goto failed; - if (joinable) { - jobp->join_cv = PR_NewCondVar(tp->join_lock); - jobp->join_wait = PR_TRUE; - if (NULL == jobp->join_cv) - goto failed; - } else { - jobp->join_cv = NULL; - } + PRJob *jobp; + + jobp = PR_NEWZAP(PRJob); + if (NULL == jobp) { + goto failed; + } + if (joinable) { + jobp->join_cv = PR_NewCondVar(tp->join_lock); + jobp->join_wait = PR_TRUE; + if (NULL == jobp->join_cv) { + goto failed; + } + } else { + jobp->join_cv = NULL; + } #ifdef OPT_WINNT - jobp->nt_notifier.jobp = jobp; + jobp->nt_notifier.jobp = jobp; #endif - return jobp; + return jobp; failed: - delete_job(jobp); - PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); - return NULL; + delete_job(jobp); + PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0); + return NULL; } /* queue a job */ PR_IMPLEMENT(PRJob *) PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable) { - PRJob *jobp; + PRJob *jobp; - jobp = alloc_job(joinable, tpool); - if (NULL == jobp) - return NULL; + jobp = alloc_job(joinable, tpool); + if (NULL == jobp) { + return NULL; + } - jobp->job_func = fn; - jobp->job_arg = arg; - jobp->tpool = tpool; + jobp->job_func = fn; + jobp->job_arg = arg; + jobp->tpool = tpool; - add_to_jobq(tpool, jobp); - return jobp; + add_to_jobq(tpool, jobp); + return jobp; } /* queue a job, when a socket is readable or writeable */ static PRJob * queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg, - PRBool joinable, io_op_type op) + PRBool joinable, io_op_type op) { - PRJob *jobp; - PRIntervalTime now; - - jobp = alloc_job(joinable, tpool); - if (NULL == jobp) { - return NULL; - } - - /* - * Add a new job to io_jobq - * wakeup io worker thread - */ - - jobp->job_func = fn; - jobp->job_arg = arg; - jobp->tpool = tpool; - jobp->iod = iod; - if (JOB_IO_READ == op) { - jobp->io_op = JOB_IO_READ; - jobp->io_poll_flags = PR_POLL_READ; - } else if (JOB_IO_WRITE == op) { - jobp->io_op = JOB_IO_WRITE; - jobp->io_poll_flags = PR_POLL_WRITE; - } else if (JOB_IO_ACCEPT == op) { - jobp->io_op = JOB_IO_ACCEPT; - jobp->io_poll_flags = PR_POLL_READ; - } else if (JOB_IO_CONNECT == op) { - jobp->io_op = JOB_IO_CONNECT; - jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT; - } else { - delete_job(jobp); - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - - jobp->timeout = iod->timeout; - if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) || - (PR_INTERVAL_NO_WAIT == iod->timeout)) { - jobp->absolute = iod->timeout; - } else { - now = PR_IntervalNow(); - jobp->absolute = now + iod->timeout; - } - - - PR_Lock(tpool->ioq.lock); - - if (PR_CLIST_IS_EMPTY(&tpool->ioq.list) || - (PR_INTERVAL_NO_TIMEOUT == iod->timeout)) { - PR_APPEND_LINK(&jobp->links,&tpool->ioq.list); - } else if (PR_INTERVAL_NO_WAIT == iod->timeout) { - PR_INSERT_LINK(&jobp->links,&tpool->ioq.list); - } else { - PRCList *qp; - PRJob *tmp_jobp; - /* - * insert into the timeout-sorted ioq - */ - for (qp = tpool->ioq.list.prev; qp != &tpool->ioq.list; - qp = qp->prev) { - tmp_jobp = JOB_LINKS_PTR(qp); - if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { - break; - } - } - PR_INSERT_AFTER(&jobp->links,qp); - } - - jobp->on_ioq = PR_TRUE; - tpool->ioq.cnt++; - /* - * notify io worker thread(s) - */ - PR_Unlock(tpool->ioq.lock); - notify_ioq(tpool); - return jobp; + PRJob *jobp; + PRIntervalTime now; + + jobp = alloc_job(joinable, tpool); + if (NULL == jobp) { + return NULL; + } + + /* + * Add a new job to io_jobq + * wakeup io worker thread + */ + + jobp->job_func = fn; + jobp->job_arg = arg; + jobp->tpool = tpool; + jobp->iod = iod; + if (JOB_IO_READ == op) { + jobp->io_op = JOB_IO_READ; + jobp->io_poll_flags = PR_POLL_READ; + } else if (JOB_IO_WRITE == op) { + jobp->io_op = JOB_IO_WRITE; + jobp->io_poll_flags = PR_POLL_WRITE; + } else if (JOB_IO_ACCEPT == op) { + jobp->io_op = JOB_IO_ACCEPT; + jobp->io_poll_flags = PR_POLL_READ; + } else if (JOB_IO_CONNECT == op) { + jobp->io_op = JOB_IO_CONNECT; + jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT; + } else { + delete_job(jobp); + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + + jobp->timeout = iod->timeout; + if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) || + (PR_INTERVAL_NO_WAIT == iod->timeout)) { + jobp->absolute = iod->timeout; + } else { + now = PR_IntervalNow(); + jobp->absolute = now + iod->timeout; + } + + + PR_Lock(tpool->ioq.lock); + + if (PR_CLIST_IS_EMPTY(&tpool->ioq.list) || + (PR_INTERVAL_NO_TIMEOUT == iod->timeout)) { + PR_APPEND_LINK(&jobp->links,&tpool->ioq.list); + } else if (PR_INTERVAL_NO_WAIT == iod->timeout) { + PR_INSERT_LINK(&jobp->links,&tpool->ioq.list); + } else { + PRCList *qp; + PRJob *tmp_jobp; + /* + * insert into the timeout-sorted ioq + */ + for (qp = tpool->ioq.list.prev; qp != &tpool->ioq.list; + qp = qp->prev) { + tmp_jobp = JOB_LINKS_PTR(qp); + if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { + break; + } + } + PR_INSERT_AFTER(&jobp->links,qp); + } + + jobp->on_ioq = PR_TRUE; + tpool->ioq.cnt++; + /* + * notify io worker thread(s) + */ + PR_Unlock(tpool->ioq.lock); + notify_ioq(tpool); + return jobp; } /* queue a job, when a socket is readable */ PR_IMPLEMENT(PRJob *) PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg, - PRBool joinable) + PRBool joinable) { - return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ)); + return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ)); } /* queue a job, when a socket is writeable */ PR_IMPLEMENT(PRJob *) PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,void * arg, - PRBool joinable) + PRBool joinable) { - return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE)); + return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE)); } /* queue a job, when a socket has a pending connection */ PR_IMPLEMENT(PRJob *) PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, - void * arg, PRBool joinable) + void * arg, PRBool joinable) { - return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_ACCEPT)); + return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_ACCEPT)); } /* queue a job, when a socket can be connected */ PR_IMPLEMENT(PRJob *) PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod, - const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable) + const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable) { - PRStatus rv; - PRErrorCode err; - - rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT); - if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)){ - /* connection pending */ - return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT)); - } + PRStatus rv; + PRErrorCode err; + + rv = PR_Connect(iod->socket, addr, PR_INTERVAL_NO_WAIT); + if ((rv == PR_FAILURE) && ((err = PR_GetError()) == PR_IN_PROGRESS_ERROR)) { + /* connection pending */ + return(queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_CONNECT)); + } /* * connection succeeded or failed; add to jobq right away */ - if (rv == PR_FAILURE) - iod->error = err; - else - iod->error = 0; + if (rv == PR_FAILURE) { + iod->error = err; + } + else { + iod->error = 0; + } return(PR_QueueJob(tpool, fn, arg, joinable)); } @@ -877,311 +919,318 @@ PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod, /* queue a job, when a timer expires */ PR_IMPLEMENT(PRJob *) PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout, - PRJobFn fn, void * arg, PRBool joinable) + PRJobFn fn, void * arg, PRBool joinable) { - PRIntervalTime now; - PRJob *jobp; - - if (PR_INTERVAL_NO_TIMEOUT == timeout) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return NULL; - } - if (PR_INTERVAL_NO_WAIT == timeout) { - /* - * no waiting; add to jobq right away - */ - return(PR_QueueJob(tpool, fn, arg, joinable)); - } - jobp = alloc_job(joinable, tpool); - if (NULL == jobp) { - return NULL; - } - - /* - * Add a new job to timer_jobq - * wakeup timer worker thread - */ - - jobp->job_func = fn; - jobp->job_arg = arg; - jobp->tpool = tpool; - jobp->timeout = timeout; - - now = PR_IntervalNow(); - jobp->absolute = now + timeout; - - - PR_Lock(tpool->timerq.lock); - jobp->on_timerq = PR_TRUE; - if (PR_CLIST_IS_EMPTY(&tpool->timerq.list)) - PR_APPEND_LINK(&jobp->links,&tpool->timerq.list); - else { - PRCList *qp; - PRJob *tmp_jobp; - /* - * insert into the sorted timer jobq - */ - for (qp = tpool->timerq.list.prev; qp != &tpool->timerq.list; - qp = qp->prev) { - tmp_jobp = JOB_LINKS_PTR(qp); - if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { - break; - } - } - PR_INSERT_AFTER(&jobp->links,qp); - } - tpool->timerq.cnt++; - /* - * notify timer worker thread(s) - */ - notify_timerq(tpool); - PR_Unlock(tpool->timerq.lock); - return jobp; + PRIntervalTime now; + PRJob *jobp; + + if (PR_INTERVAL_NO_TIMEOUT == timeout) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return NULL; + } + if (PR_INTERVAL_NO_WAIT == timeout) { + /* + * no waiting; add to jobq right away + */ + return(PR_QueueJob(tpool, fn, arg, joinable)); + } + jobp = alloc_job(joinable, tpool); + if (NULL == jobp) { + return NULL; + } + + /* + * Add a new job to timer_jobq + * wakeup timer worker thread + */ + + jobp->job_func = fn; + jobp->job_arg = arg; + jobp->tpool = tpool; + jobp->timeout = timeout; + + now = PR_IntervalNow(); + jobp->absolute = now + timeout; + + + PR_Lock(tpool->timerq.lock); + jobp->on_timerq = PR_TRUE; + if (PR_CLIST_IS_EMPTY(&tpool->timerq.list)) { + PR_APPEND_LINK(&jobp->links,&tpool->timerq.list); + } + else { + PRCList *qp; + PRJob *tmp_jobp; + /* + * insert into the sorted timer jobq + */ + for (qp = tpool->timerq.list.prev; qp != &tpool->timerq.list; + qp = qp->prev) { + tmp_jobp = JOB_LINKS_PTR(qp); + if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) { + break; + } + } + PR_INSERT_AFTER(&jobp->links,qp); + } + tpool->timerq.cnt++; + /* + * notify timer worker thread(s) + */ + notify_timerq(tpool); + PR_Unlock(tpool->timerq.lock); + return jobp; } static void notify_timerq(PRThreadPool *tp) { - /* - * wakeup the timer thread(s) - */ - PR_NotifyCondVar(tp->timerq.cv); + /* + * wakeup the timer thread(s) + */ + PR_NotifyCondVar(tp->timerq.cv); } static void notify_ioq(PRThreadPool *tp) { -PRStatus rval_status; + PRStatus rval_status; - /* - * wakeup the io thread(s) - */ - rval_status = PR_SetPollableEvent(tp->ioq.notify_fd); - PR_ASSERT(PR_SUCCESS == rval_status); + /* + * wakeup the io thread(s) + */ + rval_status = PR_SetPollableEvent(tp->ioq.notify_fd); + PR_ASSERT(PR_SUCCESS == rval_status); } /* * cancel a job * - * XXXX: is this needed? likely to be removed + * XXXX: is this needed? likely to be removed */ PR_IMPLEMENT(PRStatus) PR_CancelJob(PRJob *jobp) { - PRStatus rval = PR_FAILURE; - PRThreadPool *tp; - - if (jobp->on_timerq) { - /* - * now, check again while holding the timerq lock - */ - tp = jobp->tpool; - PR_Lock(tp->timerq.lock); - if (jobp->on_timerq) { - jobp->on_timerq = PR_FALSE; - PR_REMOVE_AND_INIT_LINK(&jobp->links); - tp->timerq.cnt--; - PR_Unlock(tp->timerq.lock); - if (!JOINABLE_JOB(jobp)) { - delete_job(jobp); - } else { - JOIN_NOTIFY(jobp); - } - rval = PR_SUCCESS; - } else - PR_Unlock(tp->timerq.lock); - } else if (jobp->on_ioq) { - /* - * now, check again while holding the ioq lock - */ - tp = jobp->tpool; - PR_Lock(tp->ioq.lock); - if (jobp->on_ioq) { - jobp->cancel_cv = PR_NewCondVar(tp->ioq.lock); - if (NULL == jobp->cancel_cv) { - PR_Unlock(tp->ioq.lock); - PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); - return PR_FAILURE; - } - /* - * mark job 'cancelled' and notify io thread(s) - * XXXX: - * this assumes there is only one io thread; when there - * are multiple threads, the io thread processing this job - * must be notified. - */ - jobp->cancel_io = PR_TRUE; - PR_Unlock(tp->ioq.lock); /* release, reacquire ioq lock */ - notify_ioq(tp); - PR_Lock(tp->ioq.lock); - while (jobp->cancel_io) - PR_WaitCondVar(jobp->cancel_cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(tp->ioq.lock); - PR_ASSERT(!jobp->on_ioq); - if (!JOINABLE_JOB(jobp)) { - delete_job(jobp); - } else { - JOIN_NOTIFY(jobp); - } - rval = PR_SUCCESS; - } else - PR_Unlock(tp->ioq.lock); - } - if (PR_FAILURE == rval) - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return rval; + PRStatus rval = PR_FAILURE; + PRThreadPool *tp; + + if (jobp->on_timerq) { + /* + * now, check again while holding the timerq lock + */ + tp = jobp->tpool; + PR_Lock(tp->timerq.lock); + if (jobp->on_timerq) { + jobp->on_timerq = PR_FALSE; + PR_REMOVE_AND_INIT_LINK(&jobp->links); + tp->timerq.cnt--; + PR_Unlock(tp->timerq.lock); + if (!JOINABLE_JOB(jobp)) { + delete_job(jobp); + } else { + JOIN_NOTIFY(jobp); + } + rval = PR_SUCCESS; + } else { + PR_Unlock(tp->timerq.lock); + } + } else if (jobp->on_ioq) { + /* + * now, check again while holding the ioq lock + */ + tp = jobp->tpool; + PR_Lock(tp->ioq.lock); + if (jobp->on_ioq) { + jobp->cancel_cv = PR_NewCondVar(tp->ioq.lock); + if (NULL == jobp->cancel_cv) { + PR_Unlock(tp->ioq.lock); + PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0); + return PR_FAILURE; + } + /* + * mark job 'cancelled' and notify io thread(s) + * XXXX: + * this assumes there is only one io thread; when there + * are multiple threads, the io thread processing this job + * must be notified. + */ + jobp->cancel_io = PR_TRUE; + PR_Unlock(tp->ioq.lock); /* release, reacquire ioq lock */ + notify_ioq(tp); + PR_Lock(tp->ioq.lock); + while (jobp->cancel_io) { + PR_WaitCondVar(jobp->cancel_cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(tp->ioq.lock); + PR_ASSERT(!jobp->on_ioq); + if (!JOINABLE_JOB(jobp)) { + delete_job(jobp); + } else { + JOIN_NOTIFY(jobp); + } + rval = PR_SUCCESS; + } else { + PR_Unlock(tp->ioq.lock); + } + } + if (PR_FAILURE == rval) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + } + return rval; } /* join a job, wait until completion */ PR_IMPLEMENT(PRStatus) PR_JoinJob(PRJob *jobp) { - if (!JOINABLE_JOB(jobp)) { - PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); - return PR_FAILURE; - } - PR_Lock(jobp->tpool->join_lock); - while(jobp->join_wait) - PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT); - PR_Unlock(jobp->tpool->join_lock); - delete_job(jobp); - return PR_SUCCESS; + if (!JOINABLE_JOB(jobp)) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return PR_FAILURE; + } + PR_Lock(jobp->tpool->join_lock); + while(jobp->join_wait) { + PR_WaitCondVar(jobp->join_cv, PR_INTERVAL_NO_TIMEOUT); + } + PR_Unlock(jobp->tpool->join_lock); + delete_job(jobp); + return PR_SUCCESS; } /* shutdown threadpool */ PR_IMPLEMENT(PRStatus) PR_ShutdownThreadPool(PRThreadPool *tpool) { -PRStatus rval = PR_SUCCESS; + PRStatus rval = PR_SUCCESS; - PR_Lock(tpool->jobq.lock); - tpool->shutdown = PR_TRUE; - PR_NotifyAllCondVar(tpool->shutdown_cv); - PR_Unlock(tpool->jobq.lock); + PR_Lock(tpool->jobq.lock); + tpool->shutdown = PR_TRUE; + PR_NotifyAllCondVar(tpool->shutdown_cv); + PR_Unlock(tpool->jobq.lock); - return rval; + return rval; } /* * join thread pool - * wait for termination of worker threads - * reclaim threadpool resources + * wait for termination of worker threads + * reclaim threadpool resources */ PR_IMPLEMENT(PRStatus) PR_JoinThreadPool(PRThreadPool *tpool) { -PRStatus rval = PR_SUCCESS; -PRCList *head; -PRStatus rval_status; + PRStatus rval = PR_SUCCESS; + PRCList *head; + PRStatus rval_status; - PR_Lock(tpool->jobq.lock); - while (!tpool->shutdown) - PR_WaitCondVar(tpool->shutdown_cv, PR_INTERVAL_NO_TIMEOUT); + PR_Lock(tpool->jobq.lock); + while (!tpool->shutdown) { + PR_WaitCondVar(tpool->shutdown_cv, PR_INTERVAL_NO_TIMEOUT); + } - /* - * wakeup worker threads - */ + /* + * wakeup worker threads + */ #ifdef OPT_WINNT - /* - * post shutdown notification for all threads - */ - { - int i; - for(i=0; i < tpool->current_threads; i++) { - PostQueuedCompletionStatus(tpool->jobq.nt_completion_port, 0, - TRUE, NULL); - } - } + /* + * post shutdown notification for all threads + */ + { + int i; + for(i=0; i < tpool->current_threads; i++) { + PostQueuedCompletionStatus(tpool->jobq.nt_completion_port, 0, + TRUE, NULL); + } + } #else - PR_NotifyAllCondVar(tpool->jobq.cv); + PR_NotifyAllCondVar(tpool->jobq.cv); #endif - /* - * wakeup io thread(s) - */ - notify_ioq(tpool); - - /* - * wakeup timer thread(s) - */ - PR_Lock(tpool->timerq.lock); - notify_timerq(tpool); - PR_Unlock(tpool->timerq.lock); - - while (!PR_CLIST_IS_EMPTY(&tpool->jobq.wthreads)) { - wthread *wthrp; - - head = PR_LIST_HEAD(&tpool->jobq.wthreads); - PR_REMOVE_AND_INIT_LINK(head); - PR_Unlock(tpool->jobq.lock); - wthrp = WTHREAD_LINKS_PTR(head); - rval_status = PR_JoinThread(wthrp->thread); - PR_ASSERT(PR_SUCCESS == rval_status); - PR_DELETE(wthrp); - PR_Lock(tpool->jobq.lock); - } - PR_Unlock(tpool->jobq.lock); - while (!PR_CLIST_IS_EMPTY(&tpool->ioq.wthreads)) { - wthread *wthrp; - - head = PR_LIST_HEAD(&tpool->ioq.wthreads); - PR_REMOVE_AND_INIT_LINK(head); - wthrp = WTHREAD_LINKS_PTR(head); - rval_status = PR_JoinThread(wthrp->thread); - PR_ASSERT(PR_SUCCESS == rval_status); - PR_DELETE(wthrp); - } - - while (!PR_CLIST_IS_EMPTY(&tpool->timerq.wthreads)) { - wthread *wthrp; - - head = PR_LIST_HEAD(&tpool->timerq.wthreads); - PR_REMOVE_AND_INIT_LINK(head); - wthrp = WTHREAD_LINKS_PTR(head); - rval_status = PR_JoinThread(wthrp->thread); - PR_ASSERT(PR_SUCCESS == rval_status); - PR_DELETE(wthrp); - } - - /* - * Delete queued jobs - */ - while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) { - PRJob *jobp; - - head = PR_LIST_HEAD(&tpool->jobq.list); - PR_REMOVE_AND_INIT_LINK(head); - jobp = JOB_LINKS_PTR(head); - tpool->jobq.cnt--; - delete_job(jobp); - } - - /* delete io jobs */ - while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) { - PRJob *jobp; - - head = PR_LIST_HEAD(&tpool->ioq.list); - PR_REMOVE_AND_INIT_LINK(head); - tpool->ioq.cnt--; - jobp = JOB_LINKS_PTR(head); - delete_job(jobp); - } - - /* delete timer jobs */ - while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) { - PRJob *jobp; - - head = PR_LIST_HEAD(&tpool->timerq.list); - PR_REMOVE_AND_INIT_LINK(head); - tpool->timerq.cnt--; - jobp = JOB_LINKS_PTR(head); - delete_job(jobp); - } - - PR_ASSERT(0 == tpool->jobq.cnt); - PR_ASSERT(0 == tpool->ioq.cnt); - PR_ASSERT(0 == tpool->timerq.cnt); - - delete_threadpool(tpool); - return rval; + /* + * wakeup io thread(s) + */ + notify_ioq(tpool); + + /* + * wakeup timer thread(s) + */ + PR_Lock(tpool->timerq.lock); + notify_timerq(tpool); + PR_Unlock(tpool->timerq.lock); + + while (!PR_CLIST_IS_EMPTY(&tpool->jobq.wthreads)) { + wthread *wthrp; + + head = PR_LIST_HEAD(&tpool->jobq.wthreads); + PR_REMOVE_AND_INIT_LINK(head); + PR_Unlock(tpool->jobq.lock); + wthrp = WTHREAD_LINKS_PTR(head); + rval_status = PR_JoinThread(wthrp->thread); + PR_ASSERT(PR_SUCCESS == rval_status); + PR_DELETE(wthrp); + PR_Lock(tpool->jobq.lock); + } + PR_Unlock(tpool->jobq.lock); + while (!PR_CLIST_IS_EMPTY(&tpool->ioq.wthreads)) { + wthread *wthrp; + + head = PR_LIST_HEAD(&tpool->ioq.wthreads); + PR_REMOVE_AND_INIT_LINK(head); + wthrp = WTHREAD_LINKS_PTR(head); + rval_status = PR_JoinThread(wthrp->thread); + PR_ASSERT(PR_SUCCESS == rval_status); + PR_DELETE(wthrp); + } + + while (!PR_CLIST_IS_EMPTY(&tpool->timerq.wthreads)) { + wthread *wthrp; + + head = PR_LIST_HEAD(&tpool->timerq.wthreads); + PR_REMOVE_AND_INIT_LINK(head); + wthrp = WTHREAD_LINKS_PTR(head); + rval_status = PR_JoinThread(wthrp->thread); + PR_ASSERT(PR_SUCCESS == rval_status); + PR_DELETE(wthrp); + } + + /* + * Delete queued jobs + */ + while (!PR_CLIST_IS_EMPTY(&tpool->jobq.list)) { + PRJob *jobp; + + head = PR_LIST_HEAD(&tpool->jobq.list); + PR_REMOVE_AND_INIT_LINK(head); + jobp = JOB_LINKS_PTR(head); + tpool->jobq.cnt--; + delete_job(jobp); + } + + /* delete io jobs */ + while (!PR_CLIST_IS_EMPTY(&tpool->ioq.list)) { + PRJob *jobp; + + head = PR_LIST_HEAD(&tpool->ioq.list); + PR_REMOVE_AND_INIT_LINK(head); + tpool->ioq.cnt--; + jobp = JOB_LINKS_PTR(head); + delete_job(jobp); + } + + /* delete timer jobs */ + while (!PR_CLIST_IS_EMPTY(&tpool->timerq.list)) { + PRJob *jobp; + + head = PR_LIST_HEAD(&tpool->timerq.list); + PR_REMOVE_AND_INIT_LINK(head); + tpool->timerq.cnt--; + jobp = JOB_LINKS_PTR(head); + delete_job(jobp); + } + + PR_ASSERT(0 == tpool->jobq.cnt); + PR_ASSERT(0 == tpool->ioq.cnt); + PR_ASSERT(0 == tpool->timerq.cnt); + + delete_threadpool(tpool); + return rval; } diff --git a/nsprpub/pr/src/misc/prtrace.c b/nsprpub/pr/src/misc/prtrace.c index 058f700b5..ef6b65104 100644 --- a/nsprpub/pr/src/misc/prtrace.c +++ b/nsprpub/pr/src/misc/prtrace.c @@ -85,18 +85,18 @@ static PRCondVar *logCVar; /* Sync Condidtion Variable */ ** Inter-thread state communication. ** Controling thread writes to logOrder under protection of logCVar ** the logging thread reads logOrder and sets logState on Notify. -** +** ** logSegments, logCount, logLostData must be read and written under ** protection of logLock, logCVar. -** +** */ static enum LogState { LogNotRunning, /* Initial state */ LogReset, /* Causes logger to re-calc controls */ LogActive, /* Logging in progress, set only by log thread */ - LogSuspend, /* Suspend Logging */ - LogResume, /* Resume Logging => LogActive */ + LogSuspend, /* Suspend Logging */ + LogResume, /* Resume Logging => LogActive */ LogStop /* Stop the log thread */ } logOrder, logState, localState; /* controlling state variables */ static PRInt32 logSegments; /* Number of buffer segments */ @@ -129,21 +129,21 @@ static void NewTraceBuffer( PRInt32 size ) logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry); PR_ASSERT( bufSize != 0); PR_LOG( lm, PR_LOG_ERROR, - ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld", - logSegments, logEntries, logEntriesPerSegment, logSegSize )); + ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld", + logSegments, logEntries, logEntriesPerSegment, logSegSize )); tBuf = PR_Malloc( bufSize ); if ( tBuf == NULL ) { PR_LOG( lm, PR_LOG_ERROR, - ("PRTrace: Failed to get trace buffer")); + ("PRTrace: Failed to get trace buffer")); PR_ASSERT( 0 ); - } + } else { PR_LOG( lm, PR_LOG_NOTICE, - ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf)); + ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf)); } next = 0; @@ -166,7 +166,7 @@ static void _PR_InitializeTrace( void ) PR_ASSERT( traceLock != NULL ); PR_Lock( traceLock ); - + PR_INIT_CLIST( &qNameList ); lm = PR_NewLogModule("trace"); @@ -179,17 +179,17 @@ static void _PR_InitializeTrace( void ) logCVar = PR_NewCondVar( logLock ); PR_Unlock( traceLock ); - return; + return; } /* end _PR_InitializeTrace() */ /* ** Create a Trace Handle */ PR_IMPLEMENT(PRTraceHandle) - PR_CreateTrace( - const char *qName, /* QName for this trace handle */ - const char *rName, /* RName for this trace handle */ - const char *description /* description for this trace handle */ +PR_CreateTrace( + const char *qName, /* QName for this trace handle */ + const char *rName, /* RName for this trace handle */ + const char *description /* description for this trace handle */ ) { QName *qnp; @@ -197,8 +197,9 @@ PR_IMPLEMENT(PRTraceHandle) PRBool matchQname = PR_FALSE; /* Self initialize, if necessary */ - if ( traceLock == NULL ) + if ( traceLock == NULL ) { _PR_InitializeTrace(); + } /* Validate input arguments */ PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX ); @@ -234,10 +235,10 @@ PR_IMPLEMENT(PRTraceHandle) { qnp = PR_NEWZAP( QName ); PR_ASSERT( qnp != NULL ); - PR_INIT_CLIST( &qnp->link ); - PR_INIT_CLIST( &qnp->rNameList ); + PR_INIT_CLIST( &qnp->link ); + PR_INIT_CLIST( &qnp->rNameList ); strcpy( qnp->name, qName ); - PR_APPEND_LINK( &qnp->link, &qNameList ); + PR_APPEND_LINK( &qnp->link, &qNameList ); } /* Do we already have a matching RName? */ @@ -267,13 +268,13 @@ PR_IMPLEMENT(PRTraceHandle) PR_ASSERT(0); } - PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ + PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ rnp->qName = qnp; /* point the RName to the QName */ /* Unlock the Facility */ PR_Unlock( traceLock ); PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t", - qName, qnp, rName, rnp )); + qName, qnp, rName, rnp )); return((PRTraceHandle)rnp); } /* end PR_CreateTrace() */ @@ -281,16 +282,16 @@ PR_IMPLEMENT(PRTraceHandle) /* ** */ -PR_IMPLEMENT(void) - PR_DestroyTrace( - PRTraceHandle handle /* Handle to be destroyed */ +PR_IMPLEMENT(void) +PR_DestroyTrace( + PRTraceHandle handle /* Handle to be destroyed */ ) { RName *rnp = (RName *)handle; QName *qnp = rnp->qName; - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s", - qnp->name, rnp->name)); + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s", + qnp->name, rnp->name)); /* Lock the Facility */ PR_Lock( traceLock ); @@ -299,8 +300,8 @@ PR_IMPLEMENT(void) ** Remove RName from the list of RNames in QName ** and free RName */ - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p", - rnp->name, rnp)); + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p", + rnp->name, rnp)); PR_REMOVE_LINK( &rnp->link ); PR_Free( rnp->lock ); PR_DELETE( rnp ); @@ -311,11 +312,11 @@ PR_IMPLEMENT(void) */ if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) ) { - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p", - qnp->name, qnp)); + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p", + qnp->name, qnp)); PR_REMOVE_LINK( &qnp->link ); PR_DELETE( qnp ); - } + } /* Unlock the Facility */ PR_Unlock( traceLock ); @@ -325,39 +326,42 @@ PR_IMPLEMENT(void) /* ** Create a TraceEntry in the trace buffer */ -PR_IMPLEMENT(void) - PR_Trace( - PRTraceHandle handle, /* use this trace handle */ - PRUint32 userData0, /* User supplied data word 0 */ - PRUint32 userData1, /* User supplied data word 1 */ - PRUint32 userData2, /* User supplied data word 2 */ - PRUint32 userData3, /* User supplied data word 3 */ - PRUint32 userData4, /* User supplied data word 4 */ - PRUint32 userData5, /* User supplied data word 5 */ - PRUint32 userData6, /* User supplied data word 6 */ - PRUint32 userData7 /* User supplied data word 7 */ +PR_IMPLEMENT(void) +PR_Trace( + PRTraceHandle handle, /* use this trace handle */ + PRUint32 userData0, /* User supplied data word 0 */ + PRUint32 userData1, /* User supplied data word 1 */ + PRUint32 userData2, /* User supplied data word 2 */ + PRUint32 userData3, /* User supplied data word 3 */ + PRUint32 userData4, /* User supplied data word 4 */ + PRUint32 userData5, /* User supplied data word 5 */ + PRUint32 userData6, /* User supplied data word 6 */ + PRUint32 userData7 /* User supplied data word 7 */ ) { PRTraceEntry *tep; PRInt32 mark; - if ( (traceState == Suspended ) - || ( ((RName *)handle)->state == Suspended )) + if ( (traceState == Suspended ) + || ( ((RName *)handle)->state == Suspended )) { return; + } /* ** Get the next trace entry slot w/ minimum delay */ PR_Lock( traceLock ); - tep = &tBuf[next++]; - if ( next > last ) + tep = &tBuf[next++]; + if ( next > last ) { next = 0; - if ( fetchLostData == PR_FALSE && next == fetchLastSeen ) + } + if ( fetchLostData == PR_FALSE && next == fetchLastSeen ) { fetchLostData = PR_TRUE; - + } + mark = next; - + PR_Unlock( traceLock ); /* @@ -400,10 +404,10 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(void) - PR_SetTraceOption( - PRTraceOption command, /* One of the enumerated values */ - void *value /* command value or NULL */ +PR_IMPLEMENT(void) +PR_SetTraceOption( + PRTraceOption command, /* One of the enumerated values */ + void *value /* command value or NULL */ ) { RName * rnp; @@ -417,79 +421,80 @@ PR_IMPLEMENT(void) NewTraceBuffer( bufSize ); PR_Unlock( traceLock ); PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize)); + ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize)); break; - + case PRTraceEnable : rnp = *(RName **)value; rnp->state = Running; PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceEnable: %p", rnp)); + ("PRSetTraceOption: PRTraceEnable: %p", rnp)); break; - + case PRTraceDisable : rnp = *(RName **)value; rnp->state = Suspended; PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceDisable: %p", rnp)); + ("PRSetTraceOption: PRTraceDisable: %p", rnp)); break; - + case PRTraceSuspend : traceState = Suspended; PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceSuspend")); + ("PRSetTraceOption: PRTraceSuspend")); break; - + case PRTraceResume : traceState = Running; PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceResume")); + ("PRSetTraceOption: PRTraceResume")); break; - + case PRTraceSuspendRecording : PR_Lock( logLock ); logOrder = LogSuspend; PR_NotifyCondVar( logCVar ); PR_Unlock( logLock ); PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceSuspendRecording")); + ("PRSetTraceOption: PRTraceSuspendRecording")); break; - + case PRTraceResumeRecording : PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceResumeRecording")); - if ( logState != LogSuspend ) + ("PRSetTraceOption: PRTraceResumeRecording")); + if ( logState != LogSuspend ) { break; + } PR_Lock( logLock ); logOrder = LogResume; PR_NotifyCondVar( logCVar ); PR_Unlock( logLock ); break; - + case PRTraceStopRecording : PR_Lock( logLock ); logOrder = LogStop; PR_NotifyCondVar( logCVar ); PR_Unlock( logLock ); PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceStopRecording")); + ("PRSetTraceOption: PRTraceStopRecording")); break; case PRTraceLockHandles : PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceLockTraceHandles")); + ("PRSetTraceOption: PRTraceLockTraceHandles")); PR_Lock( traceLock ); break; - + case PRTraceUnLockHandles : PR_LOG( lm, PR_LOG_DEBUG, - ("PRSetTraceOption: PRTraceUnLockHandles")); + ("PRSetTraceOption: PRTraceUnLockHandles")); PR_Unlock( traceLock ); break; default: PR_LOG( lm, PR_LOG_ERROR, - ("PRSetTraceOption: Invalid command %ld", command )); + ("PRSetTraceOption: Invalid command %ld", command )); PR_ASSERT( 0 ); break; } /* end switch() */ @@ -499,10 +504,10 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(void) - PR_GetTraceOption( - PRTraceOption command, /* One of the enumerated values */ - void *value /* command value or NULL */ +PR_IMPLEMENT(void) +PR_GetTraceOption( + PRTraceOption command, /* One of the enumerated values */ + void *value /* command value or NULL */ ) { switch ( command ) @@ -510,12 +515,12 @@ PR_IMPLEMENT(void) case PRTraceBufSize : *((PRInt32 *)value) = bufSize; PR_LOG( lm, PR_LOG_DEBUG, - ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize )); + ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize )); break; - + default: PR_LOG( lm, PR_LOG_ERROR, - ("PRGetTraceOption: Invalid command %ld", command )); + ("PRGetTraceOption: Invalid command %ld", command )); PR_ASSERT( 0 ); break; } /* end switch() */ @@ -525,10 +530,10 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(PRTraceHandle) - PR_GetTraceHandleFromName( - const char *qName, /* QName search argument */ - const char *rName /* RName search argument */ +PR_IMPLEMENT(PRTraceHandle) +PR_GetTraceHandleFromName( + const char *qName, /* QName search argument */ + const char *rName /* RName search argument */ ) { const char *qn, *rn, *desc; @@ -536,7 +541,7 @@ PR_IMPLEMENT(PRTraceHandle) RName *rnp = NULL; PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t" - "QName: %s, RName: %s", qName, rName )); + "QName: %s, RName: %s", qName, rName )); qh = PR_FindNextTraceQname( NULL ); while (qh != NULL) @@ -546,7 +551,7 @@ PR_IMPLEMENT(PRTraceHandle) { PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc ); if ( (strcmp( qName, qn ) == 0) - && (strcmp( rName, rn ) == 0 )) + && (strcmp( rName, rn ) == 0 )) { rnp = (RName *)rh; goto foundIt; @@ -564,12 +569,12 @@ foundIt: /* ** */ -PR_IMPLEMENT(void) - PR_GetTraceNameFromHandle( - PRTraceHandle handle, /* handle as search argument */ - const char **qName, /* pointer to associated QName */ - const char **rName, /* pointer to associated RName */ - const char **description /* pointer to associated description */ +PR_IMPLEMENT(void) +PR_GetTraceNameFromHandle( + PRTraceHandle handle, /* handle as search argument */ + const char **qName, /* pointer to associated QName */ + const char **rName, /* pointer to associated RName */ + const char **description /* pointer to associated description */ ) { RName *rnp = (RName *)handle; @@ -580,8 +585,8 @@ PR_IMPLEMENT(void) *description = rnp->desc; PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: " - "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", - qnp, rnp, qnp->name, rnp->name, rnp->desc )); + "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", + qnp, rnp, qnp->name, rnp->name, rnp->desc )); return; } /* end PR_GetTraceNameFromHandle() */ @@ -589,24 +594,28 @@ PR_IMPLEMENT(void) /* ** */ -PR_IMPLEMENT(PRTraceHandle) - PR_FindNextTraceQname( - PRTraceHandle handle +PR_IMPLEMENT(PRTraceHandle) +PR_FindNextTraceQname( + PRTraceHandle handle ) { QName *qnp = (QName *)handle; - if ( PR_CLIST_IS_EMPTY( &qNameList )) - qnp = NULL; - else if ( qnp == NULL ) + if ( PR_CLIST_IS_EMPTY( &qNameList )) { + qnp = NULL; + } + else if ( qnp == NULL ) { qnp = (QName *)PR_LIST_HEAD( &qNameList ); - else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) + } + else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) { qnp = NULL; - else + } + else { qnp = (QName *)PR_NEXT_LINK( &qnp->link ); + } - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p", - handle, qnp )); + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p", + handle, qnp )); return((PRTraceHandle)qnp); } /* end PR_FindNextTraceQname() */ @@ -614,31 +623,35 @@ PR_IMPLEMENT(PRTraceHandle) /* ** */ -PR_IMPLEMENT(PRTraceHandle) - PR_FindNextTraceRname( - PRTraceHandle rhandle, - PRTraceHandle qhandle +PR_IMPLEMENT(PRTraceHandle) +PR_FindNextTraceRname( + PRTraceHandle rhandle, + PRTraceHandle qhandle ) { RName *rnp = (RName *)rhandle; QName *qnp = (QName *)qhandle; - if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) + if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) { rnp = NULL; - else if ( rnp == NULL ) + } + else if ( rnp == NULL ) { rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList ); - else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) + } + else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) { rnp = NULL; - else + } + else { rnp = (RName *)PR_NEXT_LINK( &rnp->link ); + } - PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", - rhandle, qhandle, rnp )); + PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", + rhandle, qhandle, rnp )); return((PRTraceHandle)rnp); } /* end PR_FindNextTraceRname() */ - + /* ** */ @@ -648,11 +661,12 @@ static PRFileDesc * InitializeRecording( void ) PRFileDesc *logFile; /* Self initialize, if necessary */ - if ( traceLock == NULL ) + if ( traceLock == NULL ) { _PR_InitializeTrace(); + } PR_LOG( lm, PR_LOG_DEBUG, - ("PR_RecordTraceEntries: begins")); + ("PR_RecordTraceEntries: begins")); logLostData = 0; /* reset at entry */ logState = LogReset; @@ -662,17 +676,17 @@ static PRFileDesc * InitializeRecording( void ) if ( logFileName == NULL ) { PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: Environment variable not defined. Exiting")); + ("RecordTraceEntries: Environment variable not defined. Exiting")); return NULL; } - + /* Open the logfile */ logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 ); if ( logFile == NULL ) { PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld", - logFileName, PR_GetOSError())); + ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld", + logFileName, PR_GetOSError())); return NULL; } return logFile; @@ -685,35 +699,35 @@ static void ProcessOrders( void ) { switch ( logOrder ) { - case LogReset : - logOrder = logState = localState; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogReset")); - break; + case LogReset : + logOrder = logState = localState; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogReset")); + break; - case LogSuspend : - localState = logOrder = logState = LogSuspend; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogSuspend")); - break; + case LogSuspend : + localState = logOrder = logState = LogSuspend; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogSuspend")); + break; - case LogResume : - localState = logOrder = logState = LogActive; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogResume")); - break; + case LogResume : + localState = logOrder = logState = LogActive; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogResume")); + break; - case LogStop : - logOrder = logState = LogStop; - PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: LogStop")); - break; + case LogStop : + logOrder = logState = LogStop; + PR_LOG( lm, PR_LOG_DEBUG, + ("RecordTraceEntries: LogStop")); + break; - default : - PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: Invalid logOrder: %ld", logOrder )); - PR_ASSERT( 0 ); - break; + default : + PR_LOG( lm, PR_LOG_ERROR, + ("RecordTraceEntries: Invalid logOrder: %ld", logOrder )); + PR_ASSERT( 0 ); + break; } /* end switch() */ return ; } /* end ProcessOrders() */ @@ -727,17 +741,17 @@ static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount ) PR_LOG( lm, PR_LOG_ERROR, - ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount)); - rc = PR_Write( logFile, buf , amount ); + ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount)); + rc = PR_Write( logFile, buf, amount ); if ( rc == -1 ) PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() )); + ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() )); else if ( rc != amount ) PR_LOG( lm, PR_LOG_ERROR, - ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc)); - else + ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc)); + else PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount)); + ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount)); return; } /* end WriteTraceSegment() */ @@ -746,8 +760,8 @@ static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount ) ** */ PR_IMPLEMENT(void) - PR_RecordTraceEntries( - void +PR_RecordTraceEntries( + void ) { PRFileDesc *logFile; @@ -760,7 +774,7 @@ PR_IMPLEMENT(void) if ( logFile == NULL ) { PR_LOG( lm, PR_LOG_DEBUG, - ("PR_RecordTraceEntries: Failed to initialize")); + ("PR_RecordTraceEntries: Failed to initialize")); return; } @@ -770,12 +784,14 @@ PR_IMPLEMENT(void) PR_Lock( logLock ); - while ( (logCount == 0) && ( logOrder == logState ) ) + while ( (logCount == 0) && ( logOrder == logState ) ) { PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT ); + } /* Handle state transitions */ - if ( logOrder != logState ) + if ( logOrder != logState ) { ProcessOrders(); + } /* recalculate local controls */ if ( logCount ) @@ -787,7 +803,7 @@ PR_IMPLEMENT(void) logCount = (logCount % logSegments); currentSegment = logCount; PR_LOG( lm, PR_LOG_DEBUG, - ("PR_RecordTraceEntries: LostData segments: %ld", logLostData)); + ("PR_RecordTraceEntries: LostData segments: %ld", logLostData)); } else { @@ -795,29 +811,32 @@ PR_IMPLEMENT(void) } buf = tBuf + ( logEntriesPerSegment * currentSegment ); - if (++currentSegment >= logSegments ) + if (++currentSegment >= logSegments ) { currentSegment = 0; + } doWrite = PR_TRUE; } - else + else { doWrite = PR_FALSE; + } PR_Unlock( logLock ); if ( doWrite == PR_TRUE ) { - if ( localState != LogSuspend ) + if ( localState != LogSuspend ) { WriteTraceSegment( logFile, buf, logSegSize ); + } else PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: PR_Write(): is suspended" )); + ("RecordTraceEntries: PR_Write(): is suspended" )); } } /* end while(logState...) */ PR_Close( logFile ); PR_LOG( lm, PR_LOG_DEBUG, - ("RecordTraceEntries: exiting")); + ("RecordTraceEntries: exiting")); return; } /* end PR_RecordTraceEntries() */ @@ -825,23 +844,23 @@ PR_IMPLEMENT(void) ** */ PR_IMPLEMENT(PRIntn) - PR_GetTraceEntries( - PRTraceEntry *buffer, /* where to write output */ - PRInt32 count, /* number to get */ - PRInt32 *found /* number you got */ +PR_GetTraceEntries( + PRTraceEntry *buffer, /* where to write output */ + PRInt32 count, /* number to get */ + PRInt32 *found /* number you got */ ) { - PRInt32 rc; + PRInt32 rc; PRInt32 copied = 0; - + PR_Lock( traceLock ); - + /* ** Depending on where the LastSeen and Next indices are, - ** copy the trace buffer in one or two pieces. + ** copy the trace buffer in one or two pieces. */ PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen)); + ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen)); if ( fetchLastSeen <= next ) { @@ -850,7 +869,7 @@ PR_IMPLEMENT(PRIntn) *(buffer + copied++) = *(tBuf + fetchLastSeen++); } PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); + ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); } else /* copy in 2 parts */ { @@ -861,14 +880,14 @@ PR_IMPLEMENT(PRIntn) fetchLastSeen = 0; PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); + ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); while ( count-- > 0 && fetchLastSeen < next ) { *(buffer + copied++) = *(tBuf + fetchLastSeen++); } PR_LOG( lm, PR_LOG_ERROR, - ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); + ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); } *found = copied; |