pike.git / lib / modules / Calendar.pmod / Timezone.pmod

version» Context lines:

pike.git/lib/modules/Calendar.pmod/Timezone.pmod:55:   //! way of finding a better timezone to use.   //!   //! This timezone is limited by <ref>localtime</ref> and   //! libc to the range of <tt>time_t</tt>,   //! which is a MAXINT on most systems - 13 Dec 1901 20:45:52   //! to 19 Jan 2038 3:14:07, UTC.      #pike __REAL_VERSION__      // ---------------------------------------------------------------- - // static + // protected      Calendar.Rule.Timezone UTC=Calendar.Rule.Timezone(0,"UTC");      // ----------------------------------------------------------------   // from the system      Calendar.Rule.Timezone locale=0;      protected function(:Calendar.Rule.Timezone) _locale()   {
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:291:    int tz=z0-zl;    if (tz>86400/2) tz-=86400;    else if (tz<-86400/2) tz+=86400;   #if constant(tzname)    return ({tz,names[ll->isdst]});   #else    return ({tz,"local"});   #endif    }    -  string _sprintf(int t) { return (t=='O')?"Timezone.localtime()":0; } +  protected string _sprintf(int t) +  { +  return t=='O' && "Timezone.localtime()"; +  }       int raw_utc_offset(); // N/A but needed for interface   }      // ----------------------------------------------------------------   // magic timezones      class Timezone_Encapsule   {    Calendar.Rule.Timezone what;
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:330:    array z=what->tz_ux(unixtime);    return ({z[0]+extra_offset,z[1]+extra_name});    }       array(int) tz_jd(int julian_day)    {    array z=what->tz_jd(julian_day);    return ({z[0]+extra_offset,z[1]+extra_name});    }    -  string _sprintf(int t) +  protected string _sprintf(int t)    { -  return (t=='O')?sprintf("%O%s",what,extra_name || ""):0; +  return t=='O' && sprintf("%O%s",what,extra_name || "");    }       int raw_utc_offset() { return what->raw_utc_offset()+extra_offset; }   }      protected private Calendar.Rule.Timezone _make_new_timezone_i(string tz,    int plusminus)   {    Calendar.Rule.Timezone z=`[](tz);    if (!z) return UNDEFINED;
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:517:       class Shift    {    string dayrule;    int time;    string timetype;    int offset;    string s;    string comment;    -  void create(array a) +  protected void create(array a)    {    switch (sizeof(a))    {    case 5:    dayrule=think_day(a[0],a[1]);    comment=a[0]+" "+a[1];    // NB: The Morocco rule for 2011-07-31 has 0 as AT,    // while all others have 0:00.    [time,timetype] = parse_tod(a[2]) || ({ 0, "" });    switch (timetype)
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:544:    s=(a[4]=="-")?"":a[4];    break;    case 6:    [dayrule,comment,time,timetype,offset,s]=a;    break;    default:    error("illegal size of a\n");    }    }    -  string _sprintf(int t) +  protected string _sprintf(int t)    { -  return (t=='O')? +  return t=='O' &&    sprintf("Shift(%s,%d%s,%+d,%O)",    dayrule || "<unset>", time, -  timetype || "<unset>", offset, s): -  0; +  timetype || "<unset>", offset, s);    }       int `==(Shift other)    {    return ( dayrule==other->dayrule &&    time==other->time &&    timetype==other->timetype &&    offset==other->offset &&    s==other->s );    }
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:721:    mapping constants = all_constants() +    (["TZrules":Dummymodule(find_rule),    "TZRules":TZRules,    "TZHistory":TZHistory,    "Rule":Calendar.Rule,    "ZEROSHIFT":({0,0,0,""})    ]);       }();    -  class Rule +  class Rule(string id)    { -  string id; -  -  mapping rules=([]); -  +     array(string) lines = ({});    -  int amt=0; -  -  void create(string _id) { id=_id; } -  +     void add_line(string line)    {    lines += ({ line });    } -  +  };    -  +  class RuleCompiler(string id, array(string) lines) +  { +  mapping rules=([]); +  +  int amt=0; +     void add(string line)    {    array a= array_sscanf(line, replace("%s %s %s %s %s %s %s %[^\t ]",    " ","%*[ \t]"));       if (sizeof(a)<8) complain("illegal rule line format\n");       if (!(int)a[0] && a[0]!="min")    complain("unknown year %O\n",a[0]);   
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:939:       return ({s, last});    }          program compile()    {   #ifdef RTTZC_TIMING    float t1=time(t);   #endif + #ifdef RTTZC_DEBUG +  werror("Compiling rule %s\n", id); + #endif       foreach(lines, string line) add(line);       string c = dump();      #ifdef RTTZC_TIMING    float td=time(t);    werror("dump %O: %O\n",rule_name,td-t1);   #endif   
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:974:   #endif    return rule_cache[id] = p;    }       }       class Zone    {    string id;    -  array rules=({}); -  +     array(string) lines = ({});       array(string) aliases = ({});    -  void create(string _id) { +  protected void create(string _id) {    id=_id;    aliases = ({ id });    }       void add_alias(string zone_alias)    {    aliases += ({ zone_alias });    }       void add_line(string line)    {    lines += ({ line });    } -  +  };    -  +  class ZoneCompiler(string id, array(string) lines, array(string) aliases) +  { +  array rules=({}); +     void add(string line)    {    array a= array_sscanf(line, replace("%s %s %s %s",    " ","%*[ \t]"));    if (sizeof(a)<4)    complain("parse error\n");       a=({parse_offset(a[0]), // offset    a[1], // rule or added offset    a[2], // string
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:1165:       res+=({"array(string) zone_s=({"+    map((array)tzname,    lambda(string s) { return sprintf("%O",s); })*",",    "});\n",    "array(int) shifts=({"});    foreach (rules[..<1],array a)    res+=({a[5]+","});    res+=({"});\n",    sprintf( -  "string _sprintf(int t) { return (t=='O')?" -  "%O:0; }\n" +  "protected string _sprintf(int t) { return t=='O' &&" +  "%O; }\n"    "string zoneid=%O;\n","Rule.Timezone("+id+")",id)});       return res*"";    }       object compile()    {    string zone_name = id;    // werror("Compiling zone %O...\n", zone_name);      #ifdef RTTZC_TIMING    float t1=time(t);   #endif -  + #ifdef RTTZC_DEBUG +  werror("Compiling zone %s\n", zone_name); + #endif    -  +  rules = ({});    foreach(lines, string line) add(line);       string c=dump();      #ifdef RTTZC_TIMING    float td=time(t);    werror("dump %O: %O\n",zone_name,td-t1);    float td=time(t);   #endif      #ifdef RTTZC_DEBUG    werror("%s\n",c);   #endif       program p;    mixed err=catch { p=compile_string(c, 0, compile_handler); };    if (err)    {    int i=0;    foreach (c/"\n",string line) write("%2d: %s\n",++i,line); -  error(err); +  throw(err);    }    object zo=p();    if (zo->thezone) zo=zo->thezone;      #ifdef RTTZC_TIMING    float t3=time(t);    werror("compile %O: %O\n",zone_name,t3-td);   #endif    return zo;    }
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:1223:    }       string base_path=combine_path(__FILE__,"../tzdata/");    array files=    ({    "africa",    "antarctica",    "asia",    "australasia",    "backward", +  "backzone",    "etcetera",    "europe",    "northamerica",    "southamerica",    "pacificnew",    "systemv",    });       mapping zone_cache;    mapping rule_cache;
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:1263:   // #define RTTZC_DEBUG   // #define RTTZC_TIMING       void parse_all_rules()    {    if (!all_rules) all_rules=get_all_rules();   #ifdef RTTZC_TIMING    float t1=time(t);   #endif    -  rule_cache = ([]); -  zone_cache = ([]); +  mapping(string:Zone) new_zones = ([]); +  mapping(string:Rule) new_rules = ([]);       mapping(string:string) zone_aliases = ([]);       Zone current_zone;    foreach(all_rules/"\n", string line) {    line = (line/"#")[0];    if ((line == "") || (line == " ")) continue;       if (has_prefix(line, "Rule")) {    current_zone = 0;       string rule_name, interval;    if (sscanf(line, "Rule%*[ \t]%[^ \t]%*[ \t]%s",    rule_name, interval) == 4) { -  Rule r = rules[rule_name]; +  Rule r = new_rules[rule_name];    if (!r) { -  r = rules[rule_name] = Rule(rule_name); +  r = new_rules[rule_name] = Rule(rule_name);    }    r->add_line(interval);    } else {    werror("Failed to parse directive %O.\n", line);    }    } else if (has_prefix(line, "Zone")) {    string zone_name, zone_info;    if (sscanf(line, "Zone%*[ \t]%[^ \t]%*[ \t]%s",    zone_name, zone_info) == 4) {    // werror("Creating zone %O.\n", zone_name); -  Zone z = current_zone = zones[zone_name] = Zone(zone_name); +  Zone z = current_zone = new_zones[zone_name] = Zone(zone_name);    z->add_line(zone_info);    } else {    werror("Failed to parse directive %O.\n", line);    }    } else if (has_prefix(line, "Link")) {    string zone_name, zone_alias;    if (sscanf(line, "Link%*[ \t]%[^ \t]%*[ \t]%[^ \t]",    zone_name, zone_alias) == 4) {    Zone z = zones[zone_name];    if (z) {    z->add_alias(zone_alias); -  zones[zone_alias] = z; -  } else if (zone_cache[zone_name]) { -  zone_cache[zone_alias] = zone_cache[zone_name]; +  new_zones[zone_alias] = z;    } else {    // werror("Deferred alias: %O ==> %O.\n", zone_alias, zone_name);    zone_aliases[zone_alias] = zone_name;    }    } else {    werror("Failed to parse directive %O.\n", line);    }    } else if (current_zone) {    string prefix, suffix;    if ((sscanf(line, "%*[ \t]%[-0-9]%s", prefix, suffix) == 3) &&
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:1332:    }    }   #ifdef RTTZC_TIMING    float td=time(t);    werror("parsing: %O\n",td-t1);   #endif       // Fixup the zone aliases.    foreach(zone_aliases; string zone_alias; string zone_name) {    Zone z; -  if ((z = zones[zone_name])) { +  if ((z = new_zones[zone_name])) {    z->add_alias(zone_alias); -  zones[zone_alias] = z; -  } else if (!(zone_cache[zone_alias] = zone_cache[zone_name])) { +  new_zones[zone_alias] = z; +  } else {    werror("Zone %O is a link to a nonexistant zone %O.\n",    zone_alias, zone_name);    }    } -  +  +  zones = new_zones; +  rules = new_rules; +  +  rule_cache = ([]); +  zone_cache = ([]);    }       object find_zone(string s)    {   #ifdef RTTZC_DEBUG    werror("Searching for zone %O\n",s);   #endif    if (!zone_cache) parse_all_rules();    object ret = zone_cache[s]; -  if (ret) return ret; +  if (!undefinedp(ret)) return ret || UNDEFINED;    Zone z; -  if (!(z = zones[s])) return UNDEFINED; -  ret = z->compile(); +  if (!(z = zones[s])) { +  // Check if it's a known alias. +  // Note: TZnames.abbr2zones is sorted with +  // the most recent user first. +  array(string) a = .TZnames.abbr2zones[s]; +  if (a && sizeof(a)) +  return zone_cache[s] = find_zone(a[0]); +  return UNDEFINED; +  } +  ret = ZoneCompiler(z->id, z->lines, z->aliases)->compile();    foreach(z->aliases, string zone_alias) {    zone_cache[zone_alias] = ret;    m_delete(zones, zone_alias);    }    m_delete(zones, s);    return ret;    }       program find_rule(string s)    {    if (!rule_cache) parse_all_rules();    s = UNFIXID(s);    program ret = rule_cache[s];    if (ret) return ret;    Rule r;    if (!(r = rules[s])) return UNDEFINED; -  ret = rule_cache[s] = r->compile(); +  ret = rule_cache[s] = RuleCompiler(s, r->lines)->compile();    m_delete(rules, s);    return ret;    }       int main(int ac,array(string) am)    {    map(am[1..],find_zone);    return 0;    }   
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:1432:    protected string tzformat (string s)    {    if (names)    {    if (s=="") return names[0]; else return names[1];    }    else    return sprintf(name,s);    }    -  protected void create(int offset,string _name) +  protected void create(int offset,string name)    {    offset_to_utc=offset; -  name=_name; +  this::name=name;    if (has_value(name, "/"))    {    names=name/"/";    }    }      // the Rule:   // which julian day does dst start and end this year?    protected array(array(string|int)) jd_year_periods(int jd);   
pike.git/lib/modules/Calendar.pmod/Timezone.pmod:1482:    array b=a[i+1];    if (jd<b[0]-1) break;    if (jd<b[0]+1 &&    ux<(b[0]-2440588)*86400+b[1]) break;    i++;    }       return ({offset_to_utc-a[i][2],tzformat(a[i][3])});    }    -  string _sprintf(int t) { return (t=='O')?"Rule.Timezone("+name+")":0; } +  protected string _sprintf(int t) +  { +  return t=='O' && "Rule.Timezone("+name+")"; +  }       int raw_utc_offset() { return offset_to_utc; }    }       class TZHistory    {    constant is_timezone=1;    constant is_dst_timezone=1;      // figure out what timezone to use