strptime 0.1.6-x86-mingw32 → 0.1.7-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +5 -3
- data/appveyor.yml +3 -1
- data/ext/strptime/ruby_time.c +348 -47
- data/ext/strptime/strptime.c +22 -29
- data/ext/strptime/strptime.h +1 -0
- data/lib/strptime/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: ea1f17fa8be0f0a7ee867158f5730e98291fa2b3
         | 
| 4 | 
            +
              data.tar.gz: 5b91e5576f01eb521ed158e1c1975a9a937d4852
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 99dced6be9f623c40645dee5ef6a42ad810782b92282e70388ec984b8c8d7bfd7473fcb4991c76ad8c0779a4b82df110f78d33ec3ad394d14692b33a7153b15b
         | 
| 7 | 
            +
              data.tar.gz: 11cb3150b5dc38727ae9e175756cb7bf38faac4be15b1129c598e7942d9539ad4e721f5728da0d32873f8f78762c86db9befbd4b2b9886457b0349f09b30efc7
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/appveyor.yml
    CHANGED
    
    
    
        data/ext/strptime/ruby_time.c
    CHANGED
    
    | @@ -60,7 +60,7 @@ struct vtm { | |
| 60 60 | 
             
            struct time_object {
         | 
| 61 61 | 
             
                wideval_t timew; /* time_t value * TIME_SCALE.  possibly Rational. */
         | 
| 62 62 | 
             
                struct vtm vtm;
         | 
| 63 | 
            -
                int gmt; /* 0: | 
| 63 | 
            +
                int gmt; /* 0:localtime 1:utc 2:fixoff */
         | 
| 64 64 | 
             
                int tm_got;
         | 
| 65 65 | 
             
            };
         | 
| 66 66 | 
             
            # endif
         | 
| @@ -114,71 +114,56 @@ rb_timespec_now(struct timespec *ts) | |
| 114 114 | 
             
            }
         | 
| 115 115 | 
             
            #endif
         | 
| 116 116 |  | 
| 117 | 
            -
            /* localtime_with_gmtoff_zone */
         | 
| 118 | 
            -
            #ifdef HAVE_GMTIME_R
         | 
| 119 | 
            -
            #define rb_gmtime_r(t, tm) gmtime_r((t), (tm))
         | 
| 120 | 
            -
            #define rb_localtime_r(t, tm) localtime_r((t), (tm))
         | 
| 121 | 
            -
            #else
         | 
| 122 | 
            -
            static inline struct tm *
         | 
| 123 | 
            -
            rb_gmtime_r(const time_t *tp, struct tm *result)
         | 
| 124 | 
            -
            {
         | 
| 125 | 
            -
                struct tm *t = gmtime(tp);
         | 
| 126 | 
            -
                if (t) *result = *t;
         | 
| 127 | 
            -
                return t;
         | 
| 128 | 
            -
            }
         | 
| 129 | 
            -
             | 
| 130 | 
            -
            static inline struct tm *
         | 
| 131 | 
            -
            rb_localtime_r(const time_t *tp, struct tm *result)
         | 
| 132 | 
            -
            {
         | 
| 133 | 
            -
                struct tm *t = localtime(tp);
         | 
| 134 | 
            -
                if (t) *result = *t;
         | 
| 135 | 
            -
                return t;
         | 
| 136 | 
            -
            }
         | 
| 137 | 
            -
            #endif
         | 
| 138 | 
            -
             | 
| 139 117 | 
             
            static struct tm *
         | 
| 140 | 
            -
             | 
| 118 | 
            +
            rb_localtime_r(const time_t *t, struct tm *result)
         | 
| 141 119 | 
             
            {
         | 
| 142 120 | 
             
            #if defined __APPLE__ && defined __LP64__
         | 
| 143 121 | 
             
                if (*t != (time_t)(int)*t) return NULL;
         | 
| 144 122 | 
             
            #endif
         | 
| 145 | 
            -
             | 
| 123 | 
            +
            #ifdef HAVE_GMTIME_R
         | 
| 124 | 
            +
                result = localtime_r(t, result);
         | 
| 125 | 
            +
            #else
         | 
| 126 | 
            +
                {
         | 
| 127 | 
            +
            	struct tm *tmp = localtime(t);
         | 
| 128 | 
            +
            	if (tmp) *result = *tmp;
         | 
| 129 | 
            +
                }
         | 
| 130 | 
            +
            #endif
         | 
| 146 131 | 
             
            #if defined(HAVE_MKTIME) && defined(LOCALTIME_OVERFLOW_PROBLEM)
         | 
| 147 132 | 
             
                if (result) {
         | 
| 148 | 
            -
             | 
| 149 | 
            -
             | 
| 150 | 
            -
             | 
| 151 | 
            -
             | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
             | 
| 155 | 
            -
             | 
| 156 | 
            -
            # | 
| 157 | 
            -
             | 
| 158 | 
            -
             | 
| 159 | 
            -
            	if (*t + gmtoff1 != t2 + gmtoff2) result = NULL;
         | 
| 133 | 
            +
                    long gmtoff1 = 0;
         | 
| 134 | 
            +
                    long gmtoff2 = 0;
         | 
| 135 | 
            +
                    struct tm tmp = *result;
         | 
| 136 | 
            +
                    time_t t2;
         | 
| 137 | 
            +
                    t2 = mktime(&tmp);
         | 
| 138 | 
            +
            #  if defined(HAVE_STRUCT_TM_TM_GMTOFF)
         | 
| 139 | 
            +
                    gmtoff1 = result->tm_gmtoff;
         | 
| 140 | 
            +
                    gmtoff2 = tmp.tm_gmtoff;
         | 
| 141 | 
            +
            #  endif
         | 
| 142 | 
            +
                    if (*t + gmtoff1 != t2 + gmtoff2)
         | 
| 143 | 
            +
                        result = NULL;
         | 
| 160 144 | 
             
                }
         | 
| 161 145 | 
             
            #endif
         | 
| 162 146 | 
             
                return result;
         | 
| 163 147 | 
             
            }
         | 
| 164 | 
            -
            #define LOCALTIME(tm, result) (tzset(), | 
| 148 | 
            +
            #define LOCALTIME(tm, result) (tzset(),rb_localtime_r((tm), &(result)))
         | 
| 165 149 |  | 
| 166 | 
            -
            #if !defined(HAVE_STRUCT_TM_TM_GMTOFF)
         | 
| 167 150 | 
             
            static struct tm *
         | 
| 168 | 
            -
             | 
| 151 | 
            +
            rb_gmtime_r(const time_t *t, struct tm *result)
         | 
| 169 152 | 
             
            {
         | 
| 170 | 
            -
             | 
| 153 | 
            +
            #ifdef HAVE_GMTIME_R
         | 
| 154 | 
            +
                result = gmtime_r(t, result);
         | 
| 155 | 
            +
            #else
         | 
| 156 | 
            +
                struct tm *tmp = gmtime(t);
         | 
| 157 | 
            +
                if (tmp) *result = *tmp;
         | 
| 158 | 
            +
            #endif
         | 
| 171 159 | 
             
            #if defined(HAVE_TIMEGM) && defined(LOCALTIME_OVERFLOW_PROBLEM)
         | 
| 172 | 
            -
                if (result) {
         | 
| 173 | 
            -
            	 | 
| 174 | 
            -
            	time_t t2 = timegm(&tmp);
         | 
| 175 | 
            -
            	if (*t != t2) result = NULL;
         | 
| 160 | 
            +
                if (result && *t != timegm(result)) {
         | 
| 161 | 
            +
            	return NULL;
         | 
| 176 162 | 
             
                }
         | 
| 177 163 | 
             
            #endif
         | 
| 178 164 | 
             
                return result;
         | 
| 179 165 | 
             
            }
         | 
| 180 | 
            -
            #define GMTIME(tm, result)  | 
| 181 | 
            -
            #endif
         | 
| 166 | 
            +
            #define GMTIME(tm, result) rb_gmtime_r((tm), &(result))
         | 
| 182 167 |  | 
| 183 168 | 
             
            struct tm *
         | 
| 184 169 | 
             
            localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff,
         | 
| @@ -217,7 +202,9 @@ localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long *gmtoff, | |
| 217 202 | 
             
            }
         | 
| 218 203 |  | 
| 219 204 | 
             
            #define NDIV(x,y) (-(-((x)+1)/(y))-1)
         | 
| 205 | 
            +
            #define NMOD(x,y) ((y)-(-((x)+1)%(y))-1)
         | 
| 220 206 | 
             
            #define DIV(n,d) ((n)<0 ? NDIV((n),(d)) : (n)/(d))
         | 
| 207 | 
            +
            #define MOD(n,d) ((n)<0 ? NMOD((n),(d)) : (n)%(d))
         | 
| 221 208 |  | 
| 222 209 | 
             
            static int
         | 
| 223 210 | 
             
            leap_year_p(int y)
         | 
| @@ -263,6 +250,20 @@ static const int leap_year_days_in_month[] = { | |
| 263 250 | 
             
                31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
         | 
| 264 251 | 
             
            };
         | 
| 265 252 |  | 
| 253 | 
            +
            static int
         | 
| 254 | 
            +
            calc_tm_yday(long tm_year, int tm_mon, int tm_mday)
         | 
| 255 | 
            +
            {
         | 
| 256 | 
            +
                int tm_year_mod400 = (int)MOD(tm_year, 400);
         | 
| 257 | 
            +
                int tm_yday = tm_mday;
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                if (leap_year_p(tm_year_mod400 + 1900))
         | 
| 260 | 
            +
                    tm_yday += leap_year_yday_offset[tm_mon];
         | 
| 261 | 
            +
                else
         | 
| 262 | 
            +
                    tm_yday += common_year_yday_offset[tm_mon];
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                return tm_yday;
         | 
| 265 | 
            +
            }
         | 
| 266 | 
            +
             | 
| 266 267 | 
             
            time_t
         | 
| 267 268 | 
             
            timegm_noleapsecond(struct tm *tm)
         | 
| 268 269 | 
             
            {
         | 
| @@ -287,6 +288,306 @@ timegm_noleapsecond(struct tm *tm) | |
| 287 288 | 
             
            		    DIV(tm_year+299,400))*86400;
         | 
| 288 289 | 
             
            }
         | 
| 289 290 |  | 
| 291 | 
            +
            /* assume time_t is signed */
         | 
| 292 | 
            +
            #define SIGNED_INTEGER_MAX(sint_type) \
         | 
| 293 | 
            +
              (sint_type) \
         | 
| 294 | 
            +
              ((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) | \
         | 
| 295 | 
            +
              ((((sint_type)1) << (sizeof(sint_type) * CHAR_BIT - 2)) - 1))
         | 
| 296 | 
            +
            #define SIGNED_INTEGER_MIN(sint_type) (-SIGNED_INTEGER_MAX(sint_type)-1)
         | 
| 297 | 
            +
            # define TIMET_MAX SIGNED_INTEGER_MAX(time_t)
         | 
| 298 | 
            +
            # define TIMET_MIN SIGNED_INTEGER_MIN(time_t)
         | 
| 299 | 
            +
            # define DEBUG_FIND_TIME_NUMGUESS_INC
         | 
| 300 | 
            +
            # define DEBUG_REPORT_GUESSRANGE
         | 
| 301 | 
            +
             | 
| 302 | 
            +
            static int
         | 
| 303 | 
            +
            tmcmp(struct tm *a, struct tm *b)
         | 
| 304 | 
            +
            {
         | 
| 305 | 
            +
                if (a->tm_year != b->tm_year)
         | 
| 306 | 
            +
                    return a->tm_year < b->tm_year ? -1 : 1;
         | 
| 307 | 
            +
                else if (a->tm_mon != b->tm_mon)
         | 
| 308 | 
            +
                    return a->tm_mon < b->tm_mon ? -1 : 1;
         | 
| 309 | 
            +
                else if (a->tm_mday != b->tm_mday)
         | 
| 310 | 
            +
                    return a->tm_mday < b->tm_mday ? -1 : 1;
         | 
| 311 | 
            +
                else if (a->tm_hour != b->tm_hour)
         | 
| 312 | 
            +
                    return a->tm_hour < b->tm_hour ? -1 : 1;
         | 
| 313 | 
            +
                else if (a->tm_min != b->tm_min)
         | 
| 314 | 
            +
                    return a->tm_min < b->tm_min ? -1 : 1;
         | 
| 315 | 
            +
                else if (a->tm_sec != b->tm_sec)
         | 
| 316 | 
            +
                    return a->tm_sec < b->tm_sec ? -1 : 1;
         | 
| 317 | 
            +
                else
         | 
| 318 | 
            +
                    return 0;
         | 
| 319 | 
            +
            }
         | 
| 320 | 
            +
             | 
| 321 | 
            +
            const char *
         | 
| 322 | 
            +
            find_time_t(struct tm *tptr, int utc_p, time_t *tp)
         | 
| 323 | 
            +
            {
         | 
| 324 | 
            +
                time_t guess, guess0, guess_lo, guess_hi;
         | 
| 325 | 
            +
                struct tm *tm, tm0, tm_lo, tm_hi;
         | 
| 326 | 
            +
                int d;
         | 
| 327 | 
            +
                int find_dst;
         | 
| 328 | 
            +
                struct tm result;
         | 
| 329 | 
            +
                int status;
         | 
| 330 | 
            +
                int tptr_tm_yday;
         | 
| 331 | 
            +
             | 
| 332 | 
            +
            #define GUESS(p) (DEBUG_FIND_TIME_NUMGUESS_INC (utc_p ? rb_gmtime_r((p), &result) : LOCALTIME((p), result)))
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                guess_lo = TIMET_MIN;
         | 
| 335 | 
            +
                guess_hi = TIMET_MAX;
         | 
| 336 | 
            +
             | 
| 337 | 
            +
                find_dst = 0 < tptr->tm_isdst;
         | 
| 338 | 
            +
             | 
| 339 | 
            +
            #if defined(HAVE_MKTIME)
         | 
| 340 | 
            +
                tm0 = *tptr;
         | 
| 341 | 
            +
                if (!utc_p && (guess = mktime(&tm0)) != -1) {
         | 
| 342 | 
            +
                    tm = GUESS(&guess);
         | 
| 343 | 
            +
                    if (tm && tmcmp(tptr, tm) == 0) {
         | 
| 344 | 
            +
                        goto found;
         | 
| 345 | 
            +
                    }
         | 
| 346 | 
            +
                }
         | 
| 347 | 
            +
            #endif
         | 
| 348 | 
            +
             | 
| 349 | 
            +
                tm0 = *tptr;
         | 
| 350 | 
            +
                if (tm0.tm_mon < 0) {
         | 
| 351 | 
            +
            	tm0.tm_mon = 0;
         | 
| 352 | 
            +
            	tm0.tm_mday = 1;
         | 
| 353 | 
            +
            	tm0.tm_hour = 0;
         | 
| 354 | 
            +
            	tm0.tm_min = 0;
         | 
| 355 | 
            +
            	tm0.tm_sec = 0;
         | 
| 356 | 
            +
                }
         | 
| 357 | 
            +
                else if (11 < tm0.tm_mon) {
         | 
| 358 | 
            +
            	tm0.tm_mon = 11;
         | 
| 359 | 
            +
            	tm0.tm_mday = 31;
         | 
| 360 | 
            +
            	tm0.tm_hour = 23;
         | 
| 361 | 
            +
            	tm0.tm_min = 59;
         | 
| 362 | 
            +
            	tm0.tm_sec = 60;
         | 
| 363 | 
            +
                }
         | 
| 364 | 
            +
                else if (tm0.tm_mday < 1) {
         | 
| 365 | 
            +
            	tm0.tm_mday = 1;
         | 
| 366 | 
            +
            	tm0.tm_hour = 0;
         | 
| 367 | 
            +
            	tm0.tm_min = 0;
         | 
| 368 | 
            +
            	tm0.tm_sec = 0;
         | 
| 369 | 
            +
                }
         | 
| 370 | 
            +
                else if ((d = (leap_year_p(1900 + tm0.tm_year) ?
         | 
| 371 | 
            +
                               leap_year_days_in_month :
         | 
| 372 | 
            +
            		   common_year_days_in_month)[tm0.tm_mon]) < tm0.tm_mday) {
         | 
| 373 | 
            +
            	tm0.tm_mday = d;
         | 
| 374 | 
            +
            	tm0.tm_hour = 23;
         | 
| 375 | 
            +
            	tm0.tm_min = 59;
         | 
| 376 | 
            +
            	tm0.tm_sec = 60;
         | 
| 377 | 
            +
                }
         | 
| 378 | 
            +
                else if (tm0.tm_hour < 0) {
         | 
| 379 | 
            +
            	tm0.tm_hour = 0;
         | 
| 380 | 
            +
            	tm0.tm_min = 0;
         | 
| 381 | 
            +
            	tm0.tm_sec = 0;
         | 
| 382 | 
            +
                }
         | 
| 383 | 
            +
                else if (23 < tm0.tm_hour) {
         | 
| 384 | 
            +
            	tm0.tm_hour = 23;
         | 
| 385 | 
            +
            	tm0.tm_min = 59;
         | 
| 386 | 
            +
            	tm0.tm_sec = 60;
         | 
| 387 | 
            +
                }
         | 
| 388 | 
            +
                else if (tm0.tm_min < 0) {
         | 
| 389 | 
            +
            	tm0.tm_min = 0;
         | 
| 390 | 
            +
            	tm0.tm_sec = 0;
         | 
| 391 | 
            +
                }
         | 
| 392 | 
            +
                else if (59 < tm0.tm_min) {
         | 
| 393 | 
            +
            	tm0.tm_min = 59;
         | 
| 394 | 
            +
            	tm0.tm_sec = 60;
         | 
| 395 | 
            +
                }
         | 
| 396 | 
            +
                else if (tm0.tm_sec < 0) {
         | 
| 397 | 
            +
            	tm0.tm_sec = 0;
         | 
| 398 | 
            +
                }
         | 
| 399 | 
            +
                else if (60 < tm0.tm_sec) {
         | 
| 400 | 
            +
            	tm0.tm_sec = 60;
         | 
| 401 | 
            +
                }
         | 
| 402 | 
            +
             | 
| 403 | 
            +
                DEBUG_REPORT_GUESSRANGE;
         | 
| 404 | 
            +
                guess0 = guess = timegm_noleapsecond(&tm0);
         | 
| 405 | 
            +
                tm = GUESS(&guess);
         | 
| 406 | 
            +
                if (tm) {
         | 
| 407 | 
            +
            	d = tmcmp(tptr, tm);
         | 
| 408 | 
            +
            	if (d == 0) { goto found; }
         | 
| 409 | 
            +
            	if (d < 0) {
         | 
| 410 | 
            +
            	    guess_hi = guess;
         | 
| 411 | 
            +
            	    guess -= 24 * 60 * 60;
         | 
| 412 | 
            +
            	}
         | 
| 413 | 
            +
            	else {
         | 
| 414 | 
            +
            	    guess_lo = guess;
         | 
| 415 | 
            +
            	    guess += 24 * 60 * 60;
         | 
| 416 | 
            +
            	}
         | 
| 417 | 
            +
                    DEBUG_REPORT_GUESSRANGE;
         | 
| 418 | 
            +
            	if (guess_lo < guess && guess < guess_hi && (tm = GUESS(&guess)) != NULL) {
         | 
| 419 | 
            +
            	    d = tmcmp(tptr, tm);
         | 
| 420 | 
            +
            	    if (d == 0) { goto found; }
         | 
| 421 | 
            +
            	    if (d < 0)
         | 
| 422 | 
            +
            		guess_hi = guess;
         | 
| 423 | 
            +
            	    else
         | 
| 424 | 
            +
            		guess_lo = guess;
         | 
| 425 | 
            +
                        DEBUG_REPORT_GUESSRANGE;
         | 
| 426 | 
            +
            	}
         | 
| 427 | 
            +
                }
         | 
| 428 | 
            +
             | 
| 429 | 
            +
                tm = GUESS(&guess_lo);
         | 
| 430 | 
            +
                if (!tm) goto error;
         | 
| 431 | 
            +
                d = tmcmp(tptr, tm);
         | 
| 432 | 
            +
                if (d < 0) goto out_of_range;
         | 
| 433 | 
            +
                if (d == 0) { guess = guess_lo; goto found; }
         | 
| 434 | 
            +
                tm_lo = *tm;
         | 
| 435 | 
            +
             | 
| 436 | 
            +
                tm = GUESS(&guess_hi);
         | 
| 437 | 
            +
                if (!tm) goto error;
         | 
| 438 | 
            +
                d = tmcmp(tptr, tm);
         | 
| 439 | 
            +
                if (d > 0) goto out_of_range;
         | 
| 440 | 
            +
                if (d == 0) { guess = guess_hi; goto found; }
         | 
| 441 | 
            +
                tm_hi = *tm;
         | 
| 442 | 
            +
             | 
| 443 | 
            +
                DEBUG_REPORT_GUESSRANGE;
         | 
| 444 | 
            +
             | 
| 445 | 
            +
                status = 1;
         | 
| 446 | 
            +
             | 
| 447 | 
            +
                while (guess_lo + 1 < guess_hi) {
         | 
| 448 | 
            +
                    if (status == 0) {
         | 
| 449 | 
            +
                      binsearch:
         | 
| 450 | 
            +
                        guess = guess_lo / 2 + guess_hi / 2;
         | 
| 451 | 
            +
                        if (guess <= guess_lo)
         | 
| 452 | 
            +
                            guess = guess_lo + 1;
         | 
| 453 | 
            +
                        else if (guess >= guess_hi)
         | 
| 454 | 
            +
                            guess = guess_hi - 1;
         | 
| 455 | 
            +
                        status = 1;
         | 
| 456 | 
            +
                    }
         | 
| 457 | 
            +
                    else {
         | 
| 458 | 
            +
                        if (status == 1) {
         | 
| 459 | 
            +
                            time_t guess0_hi = timegm_noleapsecond(&tm_hi);
         | 
| 460 | 
            +
                            guess = guess_hi - (guess0_hi - guess0);
         | 
| 461 | 
            +
                            if (guess == guess_hi) /* hh:mm:60 tends to cause this condition. */
         | 
| 462 | 
            +
                                guess--;
         | 
| 463 | 
            +
                            status = 2;
         | 
| 464 | 
            +
                        }
         | 
| 465 | 
            +
                        else if (status == 2) {
         | 
| 466 | 
            +
                            time_t guess0_lo = timegm_noleapsecond(&tm_lo);
         | 
| 467 | 
            +
                            guess = guess_lo + (guess0 - guess0_lo);
         | 
| 468 | 
            +
                            if (guess == guess_lo)
         | 
| 469 | 
            +
                                guess++;
         | 
| 470 | 
            +
                            status = 0;
         | 
| 471 | 
            +
                        }
         | 
| 472 | 
            +
                        if (guess <= guess_lo || guess_hi <= guess) {
         | 
| 473 | 
            +
                            /* Precious guess is invalid. try binary search. */
         | 
| 474 | 
            +
            #ifdef DEBUG_GUESSRANGE
         | 
| 475 | 
            +
                            if (guess <= guess_lo) fprintf(stderr, "too small guess: %ld <= %ld\n", guess, guess_lo);
         | 
| 476 | 
            +
                            if (guess_hi <= guess) fprintf(stderr, "too big guess: %ld <= %ld\n", guess_hi, guess);
         | 
| 477 | 
            +
            #endif
         | 
| 478 | 
            +
                            goto binsearch;
         | 
| 479 | 
            +
                        }
         | 
| 480 | 
            +
                    }
         | 
| 481 | 
            +
             | 
| 482 | 
            +
            	tm = GUESS(&guess);
         | 
| 483 | 
            +
            	if (!tm) goto error;
         | 
| 484 | 
            +
             | 
| 485 | 
            +
            	d = tmcmp(tptr, tm);
         | 
| 486 | 
            +
             | 
| 487 | 
            +
                    if (d < 0) {
         | 
| 488 | 
            +
                        guess_hi = guess;
         | 
| 489 | 
            +
                        tm_hi = *tm;
         | 
| 490 | 
            +
                        DEBUG_REPORT_GUESSRANGE;
         | 
| 491 | 
            +
                    }
         | 
| 492 | 
            +
                    else if (d > 0) {
         | 
| 493 | 
            +
                        guess_lo = guess;
         | 
| 494 | 
            +
                        tm_lo = *tm;
         | 
| 495 | 
            +
                        DEBUG_REPORT_GUESSRANGE;
         | 
| 496 | 
            +
                    }
         | 
| 497 | 
            +
                    else {
         | 
| 498 | 
            +
                      found:
         | 
| 499 | 
            +
            	    if (!utc_p) {
         | 
| 500 | 
            +
            		/* If localtime is nonmonotonic, another result may exist. */
         | 
| 501 | 
            +
            		time_t guess2;
         | 
| 502 | 
            +
            		if (find_dst) {
         | 
| 503 | 
            +
            		    guess2 = guess - 2 * 60 * 60;
         | 
| 504 | 
            +
            		    tm = LOCALTIME(&guess2, result);
         | 
| 505 | 
            +
            		    if (tm) {
         | 
| 506 | 
            +
            			if (tptr->tm_hour != (tm->tm_hour + 2) % 24 ||
         | 
| 507 | 
            +
            			    tptr->tm_min != tm->tm_min ||
         | 
| 508 | 
            +
            			    tptr->tm_sec != tm->tm_sec) {
         | 
| 509 | 
            +
            			    guess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +
         | 
| 510 | 
            +
            				      (tm->tm_min - tptr->tm_min) * 60 +
         | 
| 511 | 
            +
            				      (tm->tm_sec - tptr->tm_sec);
         | 
| 512 | 
            +
            			    if (tptr->tm_mday != tm->tm_mday)
         | 
| 513 | 
            +
            				guess2 += 24 * 60 * 60;
         | 
| 514 | 
            +
            			    if (guess != guess2) {
         | 
| 515 | 
            +
            				tm = LOCALTIME(&guess2, result);
         | 
| 516 | 
            +
            				if (tm && tmcmp(tptr, tm) == 0) {
         | 
| 517 | 
            +
            				    if (guess < guess2)
         | 
| 518 | 
            +
            					*tp = guess;
         | 
| 519 | 
            +
            				    else
         | 
| 520 | 
            +
            					*tp = guess2;
         | 
| 521 | 
            +
                                                return NULL;
         | 
| 522 | 
            +
            				}
         | 
| 523 | 
            +
            			    }
         | 
| 524 | 
            +
            			}
         | 
| 525 | 
            +
            		    }
         | 
| 526 | 
            +
            		}
         | 
| 527 | 
            +
            		else {
         | 
| 528 | 
            +
            		    guess2 = guess + 2 * 60 * 60;
         | 
| 529 | 
            +
            		    tm = LOCALTIME(&guess2, result);
         | 
| 530 | 
            +
            		    if (tm) {
         | 
| 531 | 
            +
            			if ((tptr->tm_hour + 2) % 24 != tm->tm_hour ||
         | 
| 532 | 
            +
            			    tptr->tm_min != tm->tm_min ||
         | 
| 533 | 
            +
            			    tptr->tm_sec != tm->tm_sec) {
         | 
| 534 | 
            +
            			    guess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +
         | 
| 535 | 
            +
            				      (tm->tm_min - tptr->tm_min) * 60 +
         | 
| 536 | 
            +
            				      (tm->tm_sec - tptr->tm_sec);
         | 
| 537 | 
            +
            			    if (tptr->tm_mday != tm->tm_mday)
         | 
| 538 | 
            +
            				guess2 -= 24 * 60 * 60;
         | 
| 539 | 
            +
            			    if (guess != guess2) {
         | 
| 540 | 
            +
            				tm = LOCALTIME(&guess2, result);
         | 
| 541 | 
            +
            				if (tm && tmcmp(tptr, tm) == 0) {
         | 
| 542 | 
            +
            				    if (guess < guess2)
         | 
| 543 | 
            +
            					*tp = guess2;
         | 
| 544 | 
            +
            				    else
         | 
| 545 | 
            +
            					*tp = guess;
         | 
| 546 | 
            +
                                                return NULL;
         | 
| 547 | 
            +
            				}
         | 
| 548 | 
            +
            			    }
         | 
| 549 | 
            +
            			}
         | 
| 550 | 
            +
            		    }
         | 
| 551 | 
            +
            		}
         | 
| 552 | 
            +
            	    }
         | 
| 553 | 
            +
                        *tp = guess;
         | 
| 554 | 
            +
                        return NULL;
         | 
| 555 | 
            +
            	}
         | 
| 556 | 
            +
                }
         | 
| 557 | 
            +
             | 
| 558 | 
            +
                /* Given argument has no corresponding time_t. Let's extrapolate. */
         | 
| 559 | 
            +
                /*
         | 
| 560 | 
            +
                 *  `Seconds Since the Epoch' in SUSv3:
         | 
| 561 | 
            +
                 *  tm_sec + tm_min*60 + tm_hour*3600 + tm_yday*86400 +
         | 
| 562 | 
            +
                 *  (tm_year-70)*31536000 + ((tm_year-69)/4)*86400 -
         | 
| 563 | 
            +
                 *  ((tm_year-1)/100)*86400 + ((tm_year+299)/400)*86400
         | 
| 564 | 
            +
                 */
         | 
| 565 | 
            +
             | 
| 566 | 
            +
                tptr_tm_yday = calc_tm_yday(tptr->tm_year, tptr->tm_mon, tptr->tm_mday);
         | 
| 567 | 
            +
             | 
| 568 | 
            +
                *tp = guess_lo +
         | 
| 569 | 
            +
                      ((tptr->tm_year - tm_lo.tm_year) * 365 +
         | 
| 570 | 
            +
                       ((tptr->tm_year-69)/4) -
         | 
| 571 | 
            +
                       ((tptr->tm_year-1)/100) +
         | 
| 572 | 
            +
                       ((tptr->tm_year+299)/400) -
         | 
| 573 | 
            +
                       ((tm_lo.tm_year-69)/4) +
         | 
| 574 | 
            +
                       ((tm_lo.tm_year-1)/100) -
         | 
| 575 | 
            +
                       ((tm_lo.tm_year+299)/400) +
         | 
| 576 | 
            +
                       tptr_tm_yday -
         | 
| 577 | 
            +
                       tm_lo.tm_yday) * 86400 +
         | 
| 578 | 
            +
                      (tptr->tm_hour - tm_lo.tm_hour) * 3600 +
         | 
| 579 | 
            +
                      (tptr->tm_min - tm_lo.tm_min) * 60 +
         | 
| 580 | 
            +
                      (tptr->tm_sec - (tm_lo.tm_sec == 60 ? 59 : tm_lo.tm_sec));
         | 
| 581 | 
            +
             | 
| 582 | 
            +
                return NULL;
         | 
| 583 | 
            +
             | 
| 584 | 
            +
              out_of_range:
         | 
| 585 | 
            +
                return "time out of range";
         | 
| 586 | 
            +
             | 
| 587 | 
            +
              error:
         | 
| 588 | 
            +
                return "gmtime/localtime error";
         | 
| 589 | 
            +
            }
         | 
| 590 | 
            +
             | 
| 290 591 | 
             
            void
         | 
| 291 592 | 
             
            tm_add_offset(struct tm *tm, long diff)
         | 
| 292 593 | 
             
            {
         | 
    
        data/ext/strptime/strptime.c
    CHANGED
    
    | @@ -35,7 +35,7 @@ VALUE rb_cStrptime; | |
| 35 35 | 
             
                {
         | 
| 36 36 |  | 
| 37 37 | 
             
            #define END_INSNS_DISPATCH()                                                   \
         | 
| 38 | 
            -
                rb_bug("unknown insn: %p", GET_CURRENT_INSN()); | 
| 38 | 
            +
                rb_bug("strptime: unknown insn: %p", GET_CURRENT_INSN());                  \
         | 
| 39 39 | 
             
                } /* end of while loop */
         | 
| 40 40 |  | 
| 41 41 | 
             
            #define NEXT_INSN() TC_DISPATCH(__NEXT_INSN__)
         | 
| @@ -421,31 +421,7 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen, | |
| 421 421 | 
             
            	struct tm tm;
         | 
| 422 422 | 
             
            	time_t t;
         | 
| 423 423 | 
             
            	int gmt = gmtoff >= INT_MAX-1 ? INT_MAX-gmtoff : 2;
         | 
| 424 | 
            -
             | 
| 425 | 
            -
            	/* get current time with timezone */
         | 
| 426 | 
            -
            	rb_timespec_now(&ts);
         | 
| 427 | 
            -
            	{
         | 
| 428 | 
            -
            	    static time_t ct;
         | 
| 429 | 
            -
            	    static struct tm ctm;
         | 
| 430 | 
            -
            	    static long ctmoff;
         | 
| 431 | 
            -
            	    static long localoff;
         | 
| 432 | 
            -
            	    if (ct != ts.tv_sec) {
         | 
| 433 | 
            -
            		ct = ts.tv_sec;
         | 
| 434 | 
            -
            		localtime_with_gmtoff_zone(&ct, &ctm, &ctmoff, NULL);
         | 
| 435 | 
            -
            		localoff = ctmoff;
         | 
| 436 | 
            -
            	    }
         | 
| 437 | 
            -
            	    if (gmtoff == INT_MAX) {
         | 
| 438 | 
            -
            		gmtoff = localoff;
         | 
| 439 | 
            -
            	    }
         | 
| 440 | 
            -
            	    else if (gmtoff == INT_MAX-1) {
         | 
| 441 | 
            -
            		gmtoff = 0;
         | 
| 442 | 
            -
            	    }
         | 
| 443 | 
            -
            	    if (gmtoff != ctmoff) {
         | 
| 444 | 
            -
            		tm_add_offset(&ctm, gmtoff - ctmoff);
         | 
| 445 | 
            -
            		ctmoff = gmtoff;
         | 
| 446 | 
            -
            	    }
         | 
| 447 | 
            -
            	    memcpy(&tm, &ctm, sizeof(struct tm));
         | 
| 448 | 
            -
            	}
         | 
| 424 | 
            +
            	const char *r;
         | 
| 449 425 |  | 
| 450 426 | 
             
            	/* overwrite time */
         | 
| 451 427 | 
             
            	if (year != INT_MAX) {
         | 
| @@ -466,6 +442,17 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen, | |
| 466 442 | 
             
            	    tm.tm_sec = sec;
         | 
| 467 443 | 
             
            	}
         | 
| 468 444 | 
             
            	else {
         | 
| 445 | 
            +
            	    rb_timespec_now(&ts);
         | 
| 446 | 
            +
            	    if (gmt) {
         | 
| 447 | 
            +
            		t = ts.tv_sec;
         | 
| 448 | 
            +
            		if (gmt == 2) t += gmtoff;
         | 
| 449 | 
            +
            		gmtime_r(&t, &tm);
         | 
| 450 | 
            +
            	    }
         | 
| 451 | 
            +
            	    else {
         | 
| 452 | 
            +
            		long off;
         | 
| 453 | 
            +
            		localtime_with_gmtoff_zone(&ts.tv_sec, &tm, &off, NULL);
         | 
| 454 | 
            +
            		gmtoff = (int)off;
         | 
| 455 | 
            +
            	    }
         | 
| 469 456 | 
             
            	    if (mon != -1) goto setmonth;
         | 
| 470 457 | 
             
            	    if (mday != -1) goto setmday;
         | 
| 471 458 | 
             
            	    if (hour != -1) goto sethour;
         | 
| @@ -473,8 +460,14 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen, | |
| 473 460 | 
             
            	    if (sec != -1) tm.tm_sec = sec;
         | 
| 474 461 | 
             
            	}
         | 
| 475 462 |  | 
| 476 | 
            -
            	 | 
| 477 | 
            -
             | 
| 463 | 
            +
            	if (gmt) {
         | 
| 464 | 
            +
            	    t = timegm_noleapsecond(&tm);
         | 
| 465 | 
            +
            	    if (gmt == 2) t -= gmtoff;
         | 
| 466 | 
            +
            	}
         | 
| 467 | 
            +
            	else {
         | 
| 468 | 
            +
            	    r = find_time_t(&tm, gmt, &t);
         | 
| 469 | 
            +
            	    if (r) fail();
         | 
| 470 | 
            +
            	}
         | 
| 478 471 | 
             
            	tsp->tv_sec = t;
         | 
| 479 472 | 
             
            	tsp->tv_nsec = nsec;
         | 
| 480 473 | 
             
            	*gmtoffp = gmtoff;
         | 
| @@ -484,7 +477,7 @@ strptime_exec0(void **pc, const char *fmt, const char *str, size_t slen, | |
| 484 477 | 
             
                END_INSNS_DISPATCH();
         | 
| 485 478 |  | 
| 486 479 | 
             
                /* unreachable */
         | 
| 487 | 
            -
                rb_bug(" | 
| 480 | 
            +
                rb_bug("strptime_exec0: unreachable");
         | 
| 488 481 | 
             
                UNREACHABLE;
         | 
| 489 482 | 
             
            }
         | 
| 490 483 |  | 
    
        data/ext/strptime/strptime.h
    CHANGED
    
    | @@ -10,6 +10,7 @@ struct tm * localtime_with_gmtoff_zone(const time_t *t, struct tm *result, long | |
| 10 10 | 
             
            void rb_timespec_now(struct timespec *ts);
         | 
| 11 11 | 
             
            # endif
         | 
| 12 12 | 
             
            time_t timegm_noleapsecond(struct tm *tm);
         | 
| 13 | 
            +
            const char *find_time_t(struct tm *tptr, int utc_p, time_t *tp);
         | 
| 13 14 | 
             
            void tm_add_offset(struct tm *tm, long diff);
         | 
| 14 15 |  | 
| 15 16 | 
             
            #endif /* STRPTIME_H */
         | 
    
        data/lib/strptime/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: strptime
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1. | 
| 4 | 
            +
              version: 0.1.7
         | 
| 5 5 | 
             
            platform: x86-mingw32
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - NARUSE, Yui
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2016-03-30 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         |