~ubuntu-branches/ubuntu/quantal/ruby1.9.1/quantal

« back to all changes in this revision

Viewing changes to util.c

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2011-09-24 19:16:17 UTC
  • mfrom: (1.1.8 upstream) (13.1.7 experimental)
  • Revision ID: james.westby@ubuntu.com-20110924191617-o1qz4rcmqjot8zuy
Tags: 1.9.3~rc1-1
* New upstream release: 1.9.3 RC1.
  + Includes load.c fixes. Closes: #639959.
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 
3
3
  util.c -
4
4
 
5
 
  $Author: yugui $
 
5
  $Author: kosaki $
6
6
  created at: Fri Mar 10 17:22:34 JST 1995
7
7
 
8
8
  Copyright (C) 1993-2008 Yukihiro Matsumoto
10
10
**********************************************************************/
11
11
 
12
12
#include "ruby/ruby.h"
 
13
#include "internal.h"
13
14
 
14
15
#include <ctype.h>
15
16
#include <stdio.h>
180
181
#endif
181
182
 
182
183
#ifndef S_ISDIR
183
 
#   define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
 
184
#   define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
184
185
#endif
185
186
 
186
187
#if defined(__CYGWIN32__) || defined(_WIN32)
234
235
 * suffix = ".bak" (style 1)
235
236
 *                foo.bar => foo.bak
236
237
 *                foo.bak => foo.$$$    (fallback)
 
238
 *                makefile => makefile.bak
 
239
 * suffix = ".$$$" (style 1)
237
240
 *                foo.$$$ => foo.~~~    (fallback)
238
 
 *                makefile => makefile.bak
239
241
 *
240
242
 * suffix = "~" (style 2)
241
243
 *                foo.c => foo.c~
258
260
static const char suffix1[] = ".$$$";
259
261
static const char suffix2[] = ".~~~";
260
262
 
261
 
#define strEQ(s1,s2) (strcmp(s1,s2) == 0)
262
 
 
263
 
extern const char *ruby_find_basename(const char *, long *, long *);
264
 
extern const char *ruby_find_extname(const char *, long *);
 
263
#define strEQ(s1,s2) (strcmp((s1),(s2)) == 0)
265
264
 
266
265
void
267
266
ruby_add_suffix(VALUE str, const char *suffix)
268
267
{
269
 
    int baselen;
270
 
    int extlen = strlen(suffix);
271
 
    char *p, *q;
 
268
    long baselen;
 
269
    long extlen = strlen(suffix);
272
270
    long slen;
273
271
    char buf[1024];
274
272
    const char *name;
277
275
 
278
276
    name = StringValueCStr(str);
279
277
    slen = strlen(name);
280
 
    if (slen > sizeof(buf) - 1)
 
278
    if (slen > (long)(sizeof(buf) - 1))
281
279
        rb_fatal("Cannot do inplace edit on long filename (%ld characters)",
282
280
                 slen);
283
281
 
302
300
        rb_str_cat(str, suffix, extlen);
303
301
    }
304
302
    else {
 
303
        char *p = buf, *q;
305
304
        strncpy(buf, name, slen);
306
305
        if (ext)
307
 
            p = buf + (ext - name);
 
306
            p += (ext - name);
308
307
        else
309
 
            p = buf + slen;
 
308
            p += slen;
310
309
        p[len] = '\0';
311
310
        if (suffix[1] == '\0') {  /* Style 2 */
 
311
            q = (char *)ruby_find_basename(buf, &baselen, 0);
312
312
            if (len <= 3) {
 
313
                if (len == 0 && baselen >= 8 && p + 3 <= buf + sizeof(buf)) p[len++] = '.'; /* DOSISH */
313
314
                p[len] = *suffix;
314
315
                p[++len] = '\0';
315
316
            }
316
 
            else if ((q = (char *)ruby_find_basename(buf, &baselen, 0)) &&
317
 
                     baselen < 8) {
 
317
            else if (q && baselen < 8) {
318
318
                q += baselen;
319
319
                *q++ = *suffix;
320
320
                if (ext) {
371
371
#define D ((int*)d)
372
372
 
373
373
#define mmprepare(base, size) do {\
374
 
 if (((long)base & (0x3)) == 0)\
375
 
   if (size >= 16) mmkind = 1;\
376
 
   else            mmkind = 0;\
377
 
 else              mmkind = -1;\
378
 
 high = (size & (~0xf));\
379
 
 low  = (size &  0x0c);\
 
374
 if (((VALUE)(base) & (0x3)) == 0)\
 
375
   if ((size) >= 16) mmkind = 1;\
 
376
   else              mmkind = 0;\
 
377
 else                mmkind = -1;\
 
378
 high = ((size) & (~0xf));\
 
379
 low  = ((size) &  0x0c);\
380
380
} while (0)\
381
381
 
382
382
#define mmarg mmkind, size, high, low
441
441
 
442
442
typedef struct { char *LL, *RR; } stack_node; /* Stack structure for L,l,R,r */
443
443
#define PUSH(ll,rr) do { top->LL = (ll); top->RR = (rr); ++top; } while (0)  /* Push L,l,R,r */
444
 
#define POP(ll,rr)  do { --top; ll = top->LL; rr = top->RR; } while (0)      /* Pop L,l,R,r */
 
444
#define POP(ll,rr)  do { --top; (ll) = top->LL; (rr) = top->RR; } while (0)      /* Pop L,l,R,r */
445
445
 
446
 
#define med3(a,b,c) ((*cmp)(a,b,d)<0 ?                                   \
447
 
                       ((*cmp)(b,c,d)<0 ? b : ((*cmp)(a,c,d)<0 ? c : a)) : \
448
 
                       ((*cmp)(b,c,d)>0 ? b : ((*cmp)(a,c,d)<0 ? a : c)))
 
446
#define med3(a,b,c) ((*cmp)((a),(b),d)<0 ?                                   \
 
447
                       ((*cmp)((b),(c),d)<0 ? (b) : ((*cmp)((a),(c),d)<0 ? (c) : (a))) : \
 
448
                       ((*cmp)((b),(c),d)>0 ? (b) : ((*cmp)((a),(c),d)<0 ? (a) : (c))))
449
449
 
450
450
void
451
451
ruby_qsort(void* base, const size_t nel, const size_t size,
837
837
 
838
838
#ifdef DEBUG
839
839
#include "stdio.h"
840
 
#define Bug(x) {fprintf(stderr, "%s\n", x); exit(1);}
 
840
#define Bug(x) {fprintf(stderr, "%s\n", (x)); exit(EXIT_FAILURE);}
841
841
#endif
842
842
 
843
843
#include "stdlib.h"
922
922
 
923
923
#ifdef YES_ALIAS
924
924
typedef double double_u;
925
 
#  define dval(x) x
 
925
#  define dval(x) (x)
926
926
#  ifdef IEEE_LITTLE_ENDIAN
927
 
#    define word0(x) (((ULong *)&x)[1])
928
 
#    define word1(x) (((ULong *)&x)[0])
 
927
#    define word0(x) (((ULong *)&(x))[1])
 
928
#    define word1(x) (((ULong *)&(x))[0])
929
929
#  else
930
 
#    define word0(x) (((ULong *)&x)[0])
931
 
#    define word1(x) (((ULong *)&x)[1])
 
930
#    define word0(x) (((ULong *)&(x))[0])
 
931
#    define word1(x) (((ULong *)&(x))[1])
932
932
#  endif
933
933
#else
934
934
typedef U double_u;
935
935
#  ifdef IEEE_LITTLE_ENDIAN
936
 
#    define word0(x) (x.L[1])
937
 
#    define word1(x) (x.L[0])
 
936
#    define word0(x) ((x).L[1])
 
937
#    define word1(x) ((x).L[0])
938
938
#  else
939
 
#    define word0(x) (x.L[0])
940
 
#    define word1(x) (x.L[1])
 
939
#    define word0(x) ((x).L[0])
 
940
#    define word1(x) ((x).L[1])
941
941
#  endif
942
 
#  define dval(x) (x.d)
 
942
#  define dval(x) ((x).d)
943
943
#endif
944
944
 
945
945
/* The following definition of Storeinc is appropriate for MIPS processors.
947
947
 * #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
948
948
 */
949
949
#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm__)
950
 
#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
951
 
((unsigned short *)a)[0] = (unsigned short)c, a++)
 
950
#define Storeinc(a,b,c) (((unsigned short *)(a))[1] = (unsigned short)(b), \
 
951
((unsigned short *)(a))[0] = (unsigned short)(c), (a)++)
952
952
#else
953
 
#define Storeinc(a,b,c) (((unsigned short *)a)[0] = (unsigned short)b, \
954
 
((unsigned short *)a)[1] = (unsigned short)c, a++)
 
953
#define Storeinc(a,b,c) (((unsigned short *)(a))[0] = (unsigned short)(b), \
 
954
((unsigned short *)(a))[1] = (unsigned short)(c), (a)++)
955
955
#endif
956
956
 
957
957
/* #define P DBL_MANT_DIG */
1074
1074
#endif
1075
1075
 
1076
1076
#ifdef RND_PRODQUOT
1077
 
#define rounded_product(a,b) a = rnd_prod(a, b)
1078
 
#define rounded_quotient(a,b) a = rnd_quot(a, b)
 
1077
#define rounded_product(a,b) ((a) = rnd_prod((a), (b)))
 
1078
#define rounded_quotient(a,b) ((a) = rnd_quot((a), (b)))
1079
1079
extern double rnd_prod(double, double), rnd_quot(double, double);
1080
1080
#else
1081
 
#define rounded_product(a,b) a *= b
1082
 
#define rounded_quotient(a,b) a /= b
 
1081
#define rounded_product(a,b) ((a) *= (b))
 
1082
#define rounded_quotient(a,b) ((a) /= (b))
1083
1083
#endif
1084
1084
 
1085
1085
#define Big0 (Frac_mask1 | Exp_msk1*(DBL_MAX_EXP+Bias-1))
1178
1178
    }
1179
1179
}
1180
1180
 
1181
 
#define Bcopy(x,y) memcpy((char *)&x->sign, (char *)&y->sign, \
1182
 
y->wds*sizeof(Long) + 2*sizeof(int))
 
1181
#define Bcopy(x,y) memcpy((char *)&(x)->sign, (char *)&(y)->sign, \
 
1182
(y)->wds*sizeof(Long) + 2*sizeof(int))
1183
1183
 
1184
1184
static Bigint *
1185
1185
multadd(Bigint *b, int m, int a)   /* multiply by m and add a */
2120
2120
            static const char hexdigit[] = "0123456789abcdef0123456789ABCDEF";
2121
2121
            s0 = ++s;
2122
2122
            adj = 0;
2123
 
            aadj = -1;
 
2123
            aadj = 1.0;
 
2124
            nd0 = -4;
2124
2125
 
2125
 
            if  (!s[1]) {
2126
 
                rb_warn("malformed value for Float(): %s. Ruby 1.9.3 for later will raise an ArgumentError for the value.", s00);
2127
 
            }
2128
 
            while (*++s && (s1 = strchr(hexdigit, *s))) {
2129
 
                adj *= 16;
2130
 
                adj += (s1 - hexdigit) & 15;
 
2126
            if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
 
2127
            while (*s == '0') s++;
 
2128
            if ((s1 = strchr(hexdigit, *s)) != NULL) {
 
2129
                do {
 
2130
                    adj += aadj * ((s1 - hexdigit) & 15);
 
2131
                    nd0 += 4;
 
2132
                    aadj /= 16;
 
2133
                } while (*++s && (s1 = strchr(hexdigit, *s)));
2131
2134
            }
2132
2135
 
2133
2136
            if (*s == '.') {
2134
 
                aadj = 1.;
2135
 
                while (*++s && (s1 = strchr(hexdigit, *s))) {
2136
 
                    aadj /= 16;
 
2137
                dsign = 1;
 
2138
                if (!*++s || !(s1 = strchr(hexdigit, *s))) goto ret0;
 
2139
                if (nd0 < 0) {
 
2140
                    while (*s == '0') {
 
2141
                        s++;
 
2142
                        nd0 -= 4;
 
2143
                    }
 
2144
                }
 
2145
                for (; *s && (s1 = strchr(hexdigit, *s)); ++s) {
2137
2146
                    adj += aadj * ((s1 - hexdigit) & 15);
 
2147
                    if ((aadj /= 16) == 0.0) {
 
2148
                        while (strchr(hexdigit, *++s));
 
2149
                        break;
 
2150
                    }
2138
2151
                }
2139
2152
            }
 
2153
            else {
 
2154
                dsign = 0;
 
2155
            }
2140
2156
 
2141
2157
            if (*s == 'P' || *s == 'p') {
2142
2158
                dsign = 0x2C - *++s; /* +: 2B, -: 2D */
2143
2159
                if (abs(dsign) == 1) s++;
2144
2160
                else dsign = 1;
2145
2161
 
2146
 
               nd = 0;
2147
 
               c = *s;
2148
 
               if (c < '0' || '9' < c) goto ret0;
2149
 
               do {
 
2162
                nd = 0;
 
2163
                c = *s;
 
2164
                if (c < '0' || '9' < c) goto ret0;
 
2165
                do {
2150
2166
                    nd *= 10;
2151
2167
                    nd += c;
2152
2168
                    nd -= '0';
2153
 
                   c = *++s;
2154
 
               } while ('0' <= c && c <= '9');
2155
 
                dval(rv) = ldexp(adj, nd * dsign);
 
2169
                    c = *++s;
 
2170
                    /* Float("0x0."+("0"*267)+"1fp2095") */
 
2171
                    if (nd + dsign * nd0 > 2095) {
 
2172
                        while ('0' <= c && c <= '9') c = *++s;
 
2173
                        break;
 
2174
                    }
 
2175
                } while ('0' <= c && c <= '9');
 
2176
                nd0 += nd * dsign;
2156
2177
            }
2157
2178
            else {
2158
 
                if (aadj != -1) {
2159
 
                    rb_warn("malformed value for Float(): %s. Ruby 1.9.3 for later will raise an ArgumentError for the value.", s00);
2160
 
                }
2161
 
                dval(rv) = adj;
 
2179
                if (dsign) goto ret0;
2162
2180
            }
 
2181
            dval(rv) = ldexp(adj, nd0);
2163
2182
            goto ret;
2164
2183
        }
2165
2184
        nz0 = 1;
3138
3157
    return rv;
3139
3158
}
3140
3159
 
3141
 
#define rv_strdup(s, rve) nrv_alloc(s, rve, strlen(s)+1)
 
3160
#define rv_strdup(s, rve) nrv_alloc((s), (rve), strlen(s)+1)
3142
3161
 
3143
3162
#ifndef MULTIPLE_THREADS
3144
3163
/* freedtoa(s) must be used to free values s returned by dtoa
3154
3173
}
3155
3174
#endif
3156
3175
 
 
3176
static const char INFSTR[] = "Infinity";
 
3177
static const char NANSTR[] = "NaN";
 
3178
static const char ZEROSTR[] = "0";
 
3179
 
3157
3180
/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string.
3158
3181
 *
3159
3182
 * Inspired by "How to Print Floating-Point Numbers Accurately" by
3272
3295
        *decpt = 9999;
3273
3296
#ifdef IEEE_Arith
3274
3297
        if (!word1(d) && !(word0(d) & 0xfffff))
3275
 
            return rv_strdup("Infinity", rve);
 
3298
            return rv_strdup(INFSTR, rve);
3276
3299
#endif
3277
 
        return rv_strdup("NaN", rve);
 
3300
        return rv_strdup(NANSTR, rve);
3278
3301
    }
3279
3302
#endif
3280
3303
#ifdef IBM
3282
3305
#endif
3283
3306
    if (!dval(d)) {
3284
3307
        *decpt = 1;
3285
 
        return rv_strdup("0", rve);
 
3308
        return rv_strdup(ZEROSTR, rve);
3286
3309
    }
3287
3310
 
3288
3311
#ifdef SET_INEXACT
3906
3929
 
3907
3930
#define DBL_MANH_SIZE   20
3908
3931
#define DBL_MANL_SIZE   32
3909
 
#define INFSTR  "Infinity"
3910
 
#define NANSTR  "NaN"
3911
3932
#define DBL_ADJ (DBL_MAX_EXP - 2)
3912
3933
#define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1)
3913
3934
#define dexp_get(u) ((int)(word0(u) >> Exp_shift) & ~Exp_msk1)
3914
 
#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | (v << Exp_shift)))
3915
 
#define dmanh_get(u) ((int)(word0(u) & Frac_mask))
3916
 
#define dmanl_get(u) ((int)word1(u))
 
3935
#define dexp_set(u,v) (word0(u) = (((int)(word0(u)) & ~Exp_mask) | ((v) << Exp_shift)))
 
3936
#define dmanh_get(u) ((uint32_t)(word0(u) & Frac_mask))
 
3937
#define dmanl_get(u) ((uint32_t)word1(u))
3917
3938
 
3918
3939
 
3919
3940
/*
3941
3962
 * Outputs:     decpt, sign, rve
3942
3963
 */
3943
3964
char *
3944
 
BSD__hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
 
3965
ruby_hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign,
3945
3966
    char **rve)
3946
3967
{
3947
3968
        U u;
3960
3981
 
3961
3982
        if (isinf(d)) { /* FP_INFINITE */
3962
3983
            *decpt = INT_MAX;
3963
 
            return (nrv_alloc(INFSTR, rve, sizeof(INFSTR) - 1));
 
3984
            return rv_strdup(INFSTR, rve);
3964
3985
        }
3965
3986
        else if (isnan(d)) { /* FP_NAN */
3966
3987
            *decpt = INT_MAX;
3967
 
            return (nrv_alloc(NANSTR, rve, sizeof(NANSTR) - 1));
 
3988
            return rv_strdup(NANSTR, rve);
3968
3989
        }
3969
3990
        else if (d == 0.0) { /* FP_ZERO */
3970
3991
            *decpt = 1;
3971
 
            return (nrv_alloc("0", rve, 1));
 
3992
            return rv_strdup(ZEROSTR, rve);
3972
3993
        }
3973
3994
        else if (dexp_get(u)) { /* FP_NORMAL */
3974
3995
            *decpt = dexp_get(u) - DBL_ADJ;
3986
4007
         * enough space for all the digits.
3987
4008
         */
3988
4009
        bufsize = (ndigits > 0) ? ndigits : SIGFIGS;
3989
 
        s0 = rv_alloc(bufsize);
 
4010
        s0 = rv_alloc(bufsize+1);
3990
4011
 
3991
4012
        /* Round to the desired number of digits. */
3992
4013
        if (SIGFIGS > ndigits && ndigits > 0) {
3993
4014
                float redux = 1.0f;
 
4015
                volatile double d;
3994
4016
                int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG;
3995
4017
                dexp_set(u, offset);
3996
 
                u.d += redux;
3997
 
                u.d -= redux;
 
4018
                d = u.d;
 
4019
                d += redux;
 
4020
                d -= redux;
 
4021
                u.d = d;
3998
4022
                *decpt += dexp_get(u) - offset;
3999
4023
        }
4000
4024