- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-time/src/time.c
r321 r331 6 6 7 7 #include <math.h> 8 #include <time.h> 9 #include <mruby.h> 10 #include <mruby/class.h> 11 #include <mruby/data.h> 12 13 #ifndef DISABLE_STDIO 8 14 #include <stdio.h> 9 #include <time.h> 10 #include "mruby.h" 11 #include "mruby/class.h" 12 #include "mruby/data.h" 15 #else 16 #include <string.h> 17 #endif 18 19 #define NDIV(x,y) (-(-((x)+1)/(y))-1) 20 21 #if _MSC_VER < 1800 22 double round(double x) { 23 if (x >= 0.0) { 24 return (double)((int)(x + 0.5)); 25 } 26 else { 27 return (double)((int)(x - 0.5)); 28 } 29 } 30 #endif 13 31 14 32 #if !defined(__MINGW64__) && defined(_WIN32) … … 42 60 #endif 43 61 #endif 62 63 /* asctime(3) */ 64 /* mruby usually use its own implementation of struct tm to string conversion */ 65 /* except when DISABLE_STDIO is set. In that case, it uses asctime() or asctime_r(). */ 66 /* By default mruby tries to use asctime_r() which is reentrant. */ 67 /* Undef following macro on platforms that does not have asctime_r(). */ 68 /* #define NO_ASCTIME_R */ 44 69 45 70 /* timegm(3) */ … … 154 179 }; 155 180 181 #ifndef DISABLE_STDIO 156 182 static const char mon_names[12][4] = { 157 183 "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", … … 161 187 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", 162 188 }; 189 #endif 163 190 164 191 struct mrb_time { … … 174 201 seconds setting. Returns self on success, NULL of failure. */ 175 202 static struct mrb_time* 176 mrb_time_update_datetime(struct mrb_time *self)203 time_update_datetime(mrb_state *mrb, struct mrb_time *self) 177 204 { 178 205 struct tm *aid; … … 184 211 aid = localtime_r(&self->sec, &self->datetime); 185 212 } 186 if (!aid) return NULL; 213 if (!aid) { 214 mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, (mrb_float)self->sec)); 215 /* not reached */ 216 return NULL; 217 } 187 218 #ifdef NO_GMTIME_R 188 219 self->datetime = *aid; /* copy data */ … … 198 229 } 199 230 231 void mrb_check_num_exact(mrb_state *mrb, mrb_float num); 200 232 201 233 /* Allocates a mrb_time object and initializes it. */ … … 204 236 { 205 237 struct mrb_time *tm; 206 207 tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); 238 time_t tsec = 0; 239 240 mrb_check_num_exact(mrb, (mrb_float)sec); 241 mrb_check_num_exact(mrb, (mrb_float)usec); 242 208 243 if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) { 209 244 goto out_of_range; … … 212 247 goto out_of_range; 213 248 } 214 t m->sec = (time_t)sec;215 if ((sec > 0 && t m->sec < 0) || (sec < 0 && (double)tm->sec > sec)) {249 tsec = (time_t)sec; 250 if ((sec > 0 && tsec < 0) || (sec < 0 && (double)tsec > sec)) { 216 251 out_of_range: 217 252 mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec)); 218 253 } 254 tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); 255 tm->sec = tsec; 219 256 tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec); 220 while (tm->usec < 0) { 221 tm->sec--; 222 tm->usec += 1000000; 223 } 224 while (tm->usec >= 1000000) { 225 tm->sec++; 226 tm->usec -= 1000000; 257 if (tm->usec < 0) { 258 long sec2 = (long)NDIV(usec,1000000); /* negative div */ 259 tm->usec -= sec2 * 1000000; 260 tm->sec += sec2; 261 } 262 else if (tm->usec >= 1000000) { 263 long sec2 = (long)(usec / 1000000); 264 tm->usec -= sec2 * 1000000; 265 tm->sec += sec2; 227 266 } 228 267 tm->timezone = timezone; 229 mrb_time_update_datetime(tm);268 time_update_datetime(mrb, tm); 230 269 231 270 return tm; … … 279 318 #endif 280 319 tm->timezone = MRB_TIMEZONE_LOCAL; 281 mrb_time_update_datetime(tm);320 time_update_datetime(mrb, tm); 282 321 283 322 return tm; … … 317 356 nowtime.tm_sec = (int)asec; 318 357 nowtime.tm_isdst = -1; 358 359 if (nowtime.tm_mon < 0 || nowtime.tm_mon > 11 360 || nowtime.tm_mday < 1 || nowtime.tm_mday > 31 361 || nowtime.tm_hour < 0 || nowtime.tm_hour > 24 362 || (nowtime.tm_hour == 24 && (nowtime.tm_min > 0 || nowtime.tm_sec > 0)) 363 || nowtime.tm_min < 0 || nowtime.tm_min > 59 364 || nowtime.tm_sec < 0 || nowtime.tm_sec > 60) 365 mrb_raise(mrb, E_RUNTIME_ERROR, "argument out of range"); 366 319 367 if (timezone == MRB_TIMEZONE_UTC) { 320 368 nowsecs = timegm(&nowtime); … … 357 405 } 358 406 407 static struct mrb_time* 408 time_get_ptr(mrb_state *mrb, mrb_value time) 409 { 410 struct mrb_time *tm; 411 412 tm = DATA_GET_PTR(mrb, time, &mrb_time_type, struct mrb_time); 413 if (!tm) { 414 mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); 415 } 416 return tm; 417 } 359 418 360 419 static mrb_value … … 366 425 367 426 mrb_get_args(mrb, "o", &other); 368 tm1 = DATA_ CHECK_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);427 tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); 369 428 tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); 370 429 eq_p = tm1 && tm2 && tm1->sec == tm2->sec && tm1->usec == tm2->usec; … … 380 439 381 440 mrb_get_args(mrb, "o", &other); 382 tm1 = DATA_ CHECK_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);441 tm1 = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); 383 442 tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); 384 443 if (!tm1 || !tm2) return mrb_nil_value(); … … 406 465 407 466 mrb_get_args(mrb, "f", &f); 408 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);467 tm = time_get_ptr(mrb, self); 409 468 return mrb_time_make(mrb, mrb_obj_class(mrb, self), (double)tm->sec+f, (double)tm->usec, tm->timezone); 410 469 } … … 418 477 419 478 mrb_get_args(mrb, "o", &other); 420 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); 421 479 tm = time_get_ptr(mrb, self); 422 480 tm2 = DATA_CHECK_GET_PTR(mrb, other, &mrb_time_type, struct mrb_time); 423 481 if (tm2) { … … 439 497 struct mrb_time *tm; 440 498 441 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);499 tm = time_get_ptr(mrb, self); 442 500 return mrb_fixnum_value(tm->datetime.tm_wday); 443 501 } … … 450 508 struct mrb_time *tm; 451 509 452 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);510 tm = time_get_ptr(mrb, self); 453 511 return mrb_fixnum_value(tm->datetime.tm_yday + 1); 454 512 } … … 461 519 struct mrb_time *tm; 462 520 463 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);521 tm = time_get_ptr(mrb, self); 464 522 return mrb_fixnum_value(tm->datetime.tm_year + 1900); 465 523 } … … 472 530 struct mrb_time *tm; 473 531 474 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);532 tm = time_get_ptr(mrb, self); 475 533 if (tm->timezone <= MRB_TIMEZONE_NONE) return mrb_nil_value(); 476 534 if (tm->timezone >= MRB_TIMEZONE_LAST) return mrb_nil_value(); … … 485 543 mrb_time_asctime(mrb_state *mrb, mrb_value self) 486 544 { 487 struct mrb_time *tm; 488 struct tm *d; 545 struct mrb_time *tm = time_get_ptr(mrb, self); 546 struct tm *d = &tm->datetime; 547 int len; 548 549 #if defined(DISABLE_STDIO) 550 char *s; 551 # ifdef NO_ASCTIME_R 552 s = asctime(d); 553 # else 554 char buf[32]; 555 s = asctime_r(d, buf); 556 # endif 557 len = strlen(s)-1; /* truncate the last newline */ 558 #else 489 559 char buf[256]; 490 int len; 491 492 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); 493 d = &tm->datetime; 560 494 561 len = snprintf(buf, sizeof(buf), "%s %s %02d %02d:%02d:%02d %s%d", 495 562 wday_names[d->tm_wday], mon_names[d->tm_mon], d->tm_mday, … … 497 564 tm->timezone == MRB_TIMEZONE_UTC ? "UTC " : "", 498 565 d->tm_year + 1900); 566 #endif 499 567 return mrb_str_new(mrb, buf, len); 500 568 } … … 507 575 struct mrb_time *tm; 508 576 509 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time); 510 if (!tm) return mrb_nil_value(); 577 tm = time_get_ptr(mrb, self); 511 578 return mrb_fixnum_value(tm->datetime.tm_mday); 512 579 } … … 520 587 struct mrb_time *tm; 521 588 522 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);589 tm = time_get_ptr(mrb, self); 523 590 return mrb_bool_value(tm->datetime.tm_isdst); 524 591 } … … 532 599 struct mrb_time *tm, *tm2; 533 600 534 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);601 tm = time_get_ptr(mrb, self); 535 602 tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); 536 603 *tm2 = *tm; 537 604 tm2->timezone = MRB_TIMEZONE_UTC; 538 mrb_time_update_datetime(tm2);605 time_update_datetime(mrb, tm2); 539 606 return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); 540 607 } … … 547 614 struct mrb_time *tm, *tm2; 548 615 549 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);616 tm = time_get_ptr(mrb, self); 550 617 tm2 = (struct mrb_time *)mrb_malloc(mrb, sizeof(*tm)); 551 618 *tm2 = *tm; 552 619 tm2->timezone = MRB_TIMEZONE_LOCAL; 553 mrb_time_update_datetime(tm2);620 time_update_datetime(mrb, tm2); 554 621 return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); 555 622 } … … 562 629 struct mrb_time *tm; 563 630 564 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);631 tm = time_get_ptr(mrb, self); 565 632 return mrb_fixnum_value(tm->datetime.tm_hour); 566 633 } … … 576 643 struct mrb_time *tm; 577 644 645 n = mrb_get_args(mrb, "|iiiiiii", 646 &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec); 578 647 tm = (struct mrb_time*)DATA_PTR(self); 579 648 if (tm) { … … 582 651 mrb_data_init(self, NULL, &mrb_time_type); 583 652 584 n = mrb_get_args(mrb, "|iiiiiii",585 &ayear, &amonth, &aday, &ahour, &amin, &asec, &ausec);586 653 if (n == 0) { 587 654 tm = current_mrb_time(mrb); … … 600 667 { 601 668 mrb_value src; 669 struct mrb_time *t1, *t2; 602 670 603 671 mrb_get_args(mrb, "o", &src); … … 606 674 mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); 607 675 } 608 if (!DATA_PTR(copy)) { 609 mrb_data_init(copy, mrb_malloc(mrb, sizeof(struct mrb_time)), &mrb_time_type); 610 } 611 *(struct mrb_time *)DATA_PTR(copy) = *(struct mrb_time *)DATA_PTR(src); 676 t1 = (struct mrb_time *)DATA_PTR(copy); 677 t2 = (struct mrb_time *)DATA_PTR(src); 678 if (!t2) { 679 mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized time"); 680 } 681 if (!t1) { 682 t1 = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); 683 mrb_data_init(copy, t1, &mrb_time_type); 684 } 685 *t1 = *t2; 612 686 return copy; 613 687 } … … 620 694 struct mrb_time *tm; 621 695 622 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);696 tm = time_get_ptr(mrb, self); 623 697 tm->timezone = MRB_TIMEZONE_LOCAL; 624 mrb_time_update_datetime(tm);698 time_update_datetime(mrb, tm); 625 699 return self; 626 700 } … … 633 707 struct mrb_time *tm; 634 708 635 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);709 tm = time_get_ptr(mrb, self); 636 710 return mrb_fixnum_value(tm->datetime.tm_mday); 637 711 } … … 644 718 struct mrb_time *tm; 645 719 646 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);720 tm = time_get_ptr(mrb, self); 647 721 return mrb_fixnum_value(tm->datetime.tm_min); 648 722 } … … 655 729 struct mrb_time *tm; 656 730 657 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);731 tm = time_get_ptr(mrb, self); 658 732 return mrb_fixnum_value(tm->datetime.tm_mon + 1); 659 733 } … … 666 740 struct mrb_time *tm; 667 741 668 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);742 tm = time_get_ptr(mrb, self); 669 743 return mrb_fixnum_value(tm->datetime.tm_sec); 670 744 } … … 678 752 struct mrb_time *tm; 679 753 680 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);754 tm = time_get_ptr(mrb, self); 681 755 return mrb_float_value(mrb, (mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); 682 756 } … … 689 763 struct mrb_time *tm; 690 764 691 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);765 tm = time_get_ptr(mrb, self); 692 766 if (tm->sec > MRB_INT_MAX || tm->sec < MRB_INT_MIN) { 693 767 return mrb_float_value(mrb, (mrb_float)tm->sec); … … 703 777 struct mrb_time *tm; 704 778 705 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);779 tm = time_get_ptr(mrb, self); 706 780 if (tm->usec > MRB_INT_MAX || tm->usec < MRB_INT_MIN) { 707 781 return mrb_float_value(mrb, (mrb_float)tm->usec); … … 717 791 struct mrb_time *tm; 718 792 719 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);793 tm = time_get_ptr(mrb, self); 720 794 tm->timezone = MRB_TIMEZONE_UTC; 721 mrb_time_update_datetime(tm);795 time_update_datetime(mrb, tm); 722 796 return self; 723 797 } … … 730 804 struct mrb_time *tm; 731 805 732 tm = DATA_GET_PTR(mrb, self, &mrb_time_type, struct mrb_time);806 tm = time_get_ptr(mrb, self); 733 807 return mrb_bool_value(tm->timezone == MRB_TIMEZONE_UTC); 734 808 }
Note:
See TracChangeset
for help on using the changeset viewer.