Branch: Tag:

2017-12-25

2017-12-25 09:41:15 by Stephen R. van den Berg <srb@cuci.nl>

System.TM: Properly fixed, code reuse with mktime().

81:   #endif      #define strftime_zone strftime - #define mktime_zone mktime +    #define strptime_zone strptime   #define localtime_zone(X,Y) localtime(X)   #ifndef HAVE_EXTERNAL_TIMEZONE
89:   #endif      #define MODIFY(X) do{ THIS->modified = 1;THIS->t.X; }while(0) - #define FIX_THIS() do { \ -  if(THIS->modified){ \ -  THIS->unix_time = mktime_zone( &THIS->t ); \ -  THIS->modified = 0; \ -  } \ + #define FIX_THIS(fname) do { \ +  if(THIS->modified) \ +  fix_tm(fname, args, THIS); \    } while(0)    -  + static void fix_tm(const char*fname, int args, struct TM_struct*this) + { +  const char*tm_zone = GET_ZONE(&this->t); +  int is_utc_zone = tm_zone && !strcmp(tm_zone, "UTC"); +  if (is_utc_zone) +  this->t.tm_isdst = 0; +  this->unix_time = mktime_zone(fname, args, &this->t, is_utc_zone, 0); +  this->modified = 0; + } +    #ifdef HAVE_STRPTIME    /*! @decl int(0..1) strptime( string(1..255) format, string(1..255) data )    *!
356:    *! Unlike the system struct tm the 'year' field is not year-1900,    *! instead it is the actual year.    */ -  PIKEFUN int(0..60) `sec() { FIX_THIS();RETURN THIS->t.tm_sec; } -  PIKEFUN int(0..59) `min() { FIX_THIS();RETURN THIS->t.tm_min; } -  PIKEFUN int(0..23) `hour() { FIX_THIS();RETURN THIS->t.tm_hour; } -  PIKEFUN int(1..31) `mday() { FIX_THIS();RETURN THIS->t.tm_mday; } -  PIKEFUN int(0..11) `mon() { FIX_THIS();RETURN THIS->t.tm_mon; } +  PIKEFUN int(0..60) `sec() { FIX_THIS("sec");RETURN THIS->t.tm_sec; } +  PIKEFUN int(0..59) `min() { FIX_THIS("min");RETURN THIS->t.tm_min; } +  PIKEFUN int(0..23) `hour() { FIX_THIS("hour");RETURN THIS->t.tm_hour; } +  PIKEFUN int(1..31) `mday() { FIX_THIS("mday");RETURN THIS->t.tm_mday; } +  PIKEFUN int(0..11) `mon() { FIX_THIS("mon");RETURN THIS->t.tm_mon; }    -  PIKEFUN int `year() { FIX_THIS();RETURN THIS->t.tm_year+1900; } +  PIKEFUN int `year() { FIX_THIS("year");RETURN THIS->t.tm_year+1900; }    PIKEFUN int `sec=(int a) { MODIFY(tm_sec=a); }    PIKEFUN int `min=(int a) { MODIFY(tm_min=a); }    PIKEFUN int `hour=(int a){ MODIFY(tm_hour=a); }
377:    *! automatically using the timezone rules.    */    PIKEFUN int(-1..1) `isdst() { -  FIX_THIS(); +  FIX_THIS("isdst");    RETURN THIS->t.tm_isdst;    }   
385:    *! The day of the week, sunday is 0, saturday is 6.    *! This is calculated from the other fields and can not be changed directly.    */ -  PIKEFUN int(0..6) `wday() { FIX_THIS(); RETURN THIS->t.tm_wday; } +  PIKEFUN int(0..6) `wday() { FIX_THIS("wday"); RETURN THIS->t.tm_wday; }       /*! @decl int yday    *! The day of the year, from 0 (the first day) to 365    *! This is calculated from the other fields and can not be changed directly.    */ -  PIKEFUN int(0..365) `yday() { FIX_THIS(); RETURN THIS->t.tm_yday; } +  PIKEFUN int(0..365) `yday() { FIX_THIS("yday"); RETURN THIS->t.tm_yday; }       /*! @decl int unix_time()    *! Return the unix time corresponding to this time_t. If no time
399:    */    PIKEFUN int unix_time()    { -  FIX_THIS(); +  FIX_THIS("unix_time");    RETURN THIS->unix_time;    }   
410:    */    PIKEFUN string asctime()    { -  FIX_THIS(); +  FIX_THIS("asctime");    {   #define STRFTIME_MAXSIZE 26    char s[STRFTIME_MAXSIZE];
485:    *! The timezone of this structure    */    PIKEFUN string `zone() { -  FIX_THIS(); +  FIX_THIS("zone");    if( GET_ZONE(&(THIS->t)) )    push_text( GET_ZONE(&(THIS->t)) );    else
496:    *! The offset from GMT for the time in this tm-struct    */    PIKEFUN int `gmtoff() { -  FIX_THIS(); +  FIX_THIS("gmtoff");    push_int( GET_GMTOFF(&(THIS->t)) );    }   
579:    string|void timezone )    {    struct tm *t = &THIS->t; -  int use_utc = !timezone || !strcmp(timezone->str, "UTC"); +  int use_utc;    t->tm_isdst = use_utc ? 0 : -1;    t->tm_year = year - 1900;    t->tm_mon = mon;
587:    t->tm_hour = hour;    t->tm_min = min;    t->tm_sec = sec; -  t->tm_wday = -1; /* Conversion valid flag */ +  use_utc = 0; +  if (timezone) { +  if (strcmp(timezone->str, "UTC")) +  Pike_error("Timezone must either be UTC or omitted.\n"); +  use_utc = 1; +  }    if (THIS->set_zone) {    free_string(THIS->set_zone);    THIS->set_zone = NULL;    } -  THIS->unix_time = mktime_zone( t ); -  if (t->tm_wday < 0) -  Pike_error("Invalid time conversion\n"); +  if (use_utc) +  t->tm_isdst = 0; +  THIS->unix_time = mktime_zone("TM", args, &THIS->t, use_utc, 0);    /* Setting it to other timezones than UTC is not supported (yet) */ -  if (use_utc) { +  if (use_utc)    SET_ZONE(t, "UTC"); -  THIS->unix_time += GET_GMTOFF(t); +     } -  } +       #ifdef PIKE_NULL_IS_SPECIAL    INIT {