a580e12000-09-27Fredrik Hübinette (Hubbe) #pike __REAL_VERSION__
c3d8282000-09-26Fredrik Hübinette (Hubbe) 
78fd532000-07-12Mirar (Pontus Hagland) import ".";
68e10f2000-09-07Mirar (Pontus Hagland) string all_data=0; mapping loaded_events=([]); mapping loaded_regions=([]);
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) constant month2n=(["Jan":1,"Feb":2,"Mar":3,"Apr":4,"May":5,"Jun":6, "Jul":7,"Aug":8,"Sep":9,"Oct":10,"Nov":11,"Dec":12]); constant wd2n=(["Mon":1,"Tue":2,"Wed":3,"Thu":4,"Fri":5,"Sat":6,"Sun":7]);
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) void read_all_data() {
4839dd2001-09-02Marcus Comstedt  all_data=master()->master_read_file(
68e10f2000-09-07Mirar (Pontus Hagland)  combine_path(__FILE__,"../events/regional"));
78fd532000-07-12Mirar (Pontus Hagland) }
68e10f2000-09-07Mirar (Pontus Hagland) Event.Event make_event(string source)
78fd532000-07-12Mirar (Pontus Hagland) {
68e10f2000-09-07Mirar (Pontus Hagland)  string id; string flags; string s; string rule; if (sscanf(source, "%*[ \t]Event%*[ \t]" "\"%[^\"]\"%*[ \t]%[-a-z]%*[ \t]" "\"%s\"%*[ \t]%[^\n]", id,flags,s,rule)!=9) error("Events: rule error; unknown format:\n%O\n",source);
3b6a322003-08-07Martin Nilsson  if (has_value(rule, "\""))
78fd532000-07-12Mirar (Pontus Hagland)  {
68e10f2000-09-07Mirar (Pontus Hagland)  if (sscanf(source, "%*[ \t]Event%*[ \t]" "\"%[^\"]\"%*[ \t]%[-a-z]%*[ \t]" "\"%s\n", id,flags,s)!=7) error("Events: rule error; unknown format:\n%O\n",source); sscanf(replace(s,"\\\"","»»»1902318231»»»"), "%s\"%*[ \t]%s",s,rule); s=replace(s,"»»»1902318231»»»","\"");
78fd532000-07-12Mirar (Pontus Hagland)  }
68e10f2000-09-07Mirar (Pontus Hagland)  string ruleid=rule,mn,wd,a; int md,n,m; int days=1; sscanf(rule,"%[^ \t\n]",ruleid); switch (ruleid)
78fd532000-07-12Mirar (Pontus Hagland)  {
68e10f2000-09-07Mirar (Pontus Hagland)  case "Fixed": if (sscanf(rule,"Fixed%*[ \t]%s%*[ \t]%d%*[ \t]%d days", mn,md,days)>=4 && month2n[mn]) return Event.Gregorian_Fixed(id,s,md,month2n[mn]); error("Events: rule error; unknown rule format:\n%O\n",source); case "Julian_Fixed": if (sscanf(rule,"Julian_Fixed%*[ \t]%s%*[ \t]%d%*[ \t]%d days", mn,md,days)>=4 && month2n[mn]) return Event.Julian_Fixed(id,s,md,month2n[mn]); error("Events: rule error; unknown rule format:\n%O\n",source); case "Islamic_Fixed": case "Coptic_Fixed": // not supported yet return Event.NullEvent(id,s); case "WDRel": // WDRel May Fri 1st
431ce62007-01-02Martin Nilsson  days=1;
68e10f2000-09-07Mirar (Pontus Hagland)  if (sscanf(rule, "WDRel%*[ \t]%s%*[ \t]%s%*[ \t]%d%*[a-z]%*[ \t]%d days",
431ce62007-01-02Martin Nilsson  mn,wd,n,days)>=7 &&
68e10f2000-09-07Mirar (Pontus Hagland)  month2n[mn] && wd2n[wd] && n>0) { Event.Event e= Event.Monthday_Weekday_Relative( id,s,1,month2n[mn],wd2n[wd],n,1); e->nd=days; return e; } // WDRel May Fri last
431ce62007-01-02Martin Nilsson  days=1;
68e10f2000-09-07Mirar (Pontus Hagland)  if (sscanf(rule, "WDRel%*[ \t]%s%*[ \t]%s%*[ \t]%s%*[ \t]%d days",
431ce62007-01-02Martin Nilsson  mn,wd,a,days)>=6 && a=="last" &&
68e10f2000-09-07Mirar (Pontus Hagland)  (m=month2n[mn]) && wd2n[wd]) { m=(m%12)+1; Event.Event e= Event.Monthday_Weekday_Relative(
97b72f2001-05-27Mirar (Pontus Hagland)  id,s,1,m,wd2n[wd],-1,0);
68e10f2000-09-07Mirar (Pontus Hagland)  e->nd=days; return e; } // WDRel May 17 Fri +17 excl
431ce62007-01-02Martin Nilsson  a=0; days=1;
68e10f2000-09-07Mirar (Pontus Hagland)  if (sscanf(rule,
4f7b302000-09-30Mirar (Pontus Hagland)  "WDRel%*[ \t]%[A-z]%*[ \t]%d%*[ \t]%s%*[ \t]" "%d%*[ \t]%[a-z]%*[ \t]%d days",
431ce62007-01-02Martin Nilsson  mn,md,wd,n,a,days)>=10 && a && a!="" &&
68e10f2000-09-07Mirar (Pontus Hagland)  (m=month2n[mn]) && wd2n[wd]) {
4f7b302000-09-30Mirar (Pontus Hagland)  if (!(<"incl","excl">)[a]) error("Events: rule error; expected incl or excl, not %O" ":\n%O\n",a,source);
68e10f2000-09-07Mirar (Pontus Hagland)  m=(m%12)+1; Event.Event e= Event.Monthday_Weekday_Relative(
4f7b302000-09-30Mirar (Pontus Hagland)  id,s,md,month2n[mn],wd2n[wd],n,a!="excl");
68e10f2000-09-07Mirar (Pontus Hagland)  e->nd=days; return e; } // WDRel May 17 Fri +17
431ce62007-01-02Martin Nilsson  days=1;
68e10f2000-09-07Mirar (Pontus Hagland)  if (sscanf(rule,
4f7b302000-09-30Mirar (Pontus Hagland)  "WDRel%*[ \t]%[A-z]%*[ \t]%d%*[ \t]%[^ \t]%*[ \t]" "%d%*[ \t]%d days",
431ce62007-01-02Martin Nilsson  mn,md,wd,n,days)>=8 &&
68e10f2000-09-07Mirar (Pontus Hagland)  (m=month2n[mn]) && wd2n[wd]) { m=(m%12)+1; Event.Event e= Event.Monthday_Weekday_Relative( id,s,md,month2n[mn],wd2n[wd],n,1); e->nd=days; return e; } error("Events: rule error; unknown rule format:\n%O\n",source); case "Easter": if (sscanf(rule,"Easter%*[ \t]%d%*[ \t]%d days", n,days)>=2) return Event.Easter_Relative(id,s,n); error("Events: rule error; unknown rule format:\n%O\n",source); case "Julian_Easter": if (sscanf(rule,"Julian_Easter%*[ \t]%d%*[ \t]%d days", n,days)>=2) return Event.Easter_Relative(id,s,n); error("Events: rule error; unknown rule format:\n%O\n",source); case "Weekday": if (sscanf(rule,"Weekday%*[ \t]%s%*[ \t]%d days", wd,days)>=2 && (n=wd2n[wd])) return Event.Weekday(n,id); error("Events: rule error; unknown rule format:\n%O\n",source); case "Null": return Event.NullEvent(id,s); default: error("Events: rule error; unknown rule id:\n%O\n",source);
78fd532000-07-12Mirar (Pontus Hagland)  } }
4f7b302000-09-30Mirar (Pontus Hagland) constant nd_m_yd=(["jan":0,"feb":31,"mar":59,"apr":90, "may":120,"jun":151,"jul":181,"aug":212, "sep":243,"oct":273,"nov":304,"dec":334]); constant nd_m_nd=(["jan":31,"feb":28,"mar":31,"apr":30, "may":31,"jun":30,"jul":31,"aug":31, "sep":30,"oct":31,"nov":30,"dec":31]); Event.Namedays new_namedays_object(string id,string name, int start,int stop,int leapdayshift, array(array(string)) names) { return Event.Namedays(id,name,names,0, start,stop,leapdayshift); } mapping made_namedays=([]); string read_all_namedays() {
4839dd2001-09-02Marcus Comstedt  return master()->master_read_file(
4f7b302000-09-30Mirar (Pontus Hagland)  combine_path(__FILE__,"../events/namedays")); } Event.Namedays find_namedays(string region)
78fd532000-07-12Mirar (Pontus Hagland) {
4f7b302000-09-30Mirar (Pontus Hagland)  string id="namedays/"+region; object res; if ( (res=made_namedays[region]) ) return res; string all=read_all_namedays(); int i=search(all,"\nRegion \""+region+"\"");
f2d7a62002-02-14Martin Nilsson  if (i==-1) return UNDEFINED; // not found
4f7b302000-09-30Mirar (Pontus Hagland)  int i2=search(all,"\nRegion",i+1);
ead9722003-01-20Martin Nilsson  if (i2==-1) i2=sizeof(all)-1;
4f7b302000-09-30Mirar (Pontus Hagland)  array(array(string)) names=0; int start=-1,stop=-1; int leapdayshift=2000;
dc29c62001-09-19Mirar (Pontus Hagland)  string charset="iso-8859-1"; function(string:string) decoder=0;
4f7b302000-09-30Mirar (Pontus Hagland)  foreach (all[i..i2]/"\n",string line) { string w="",s; sscanf(line,"%*[ \t]%[^ \t]%*[ \t]%s",w,s); #if 1 switch (w=lower_case(w)) { case "": case "region": // ignore break; case "leapdayshift": sscanf(s,"%d",leapdayshift); break;
dc29c62001-09-19Mirar (Pontus Hagland)  case "charset": sscanf(s,"%s",charset); object dec=Locale.Charset.decoder(charset); decoder=lambda(string s) { return dec->feed(s)->drain(); }; break;
4f7b302000-09-30Mirar (Pontus Hagland)  case "period": if (names) if (res) res|=new_namedays_object(region,id, start,stop,leapdayshift,names); else res=new_namedays_object(region,id, start,stop,leapdayshift,names); names=0; sscanf(s,"%[0-9]-%[0-9]",string sstart,string sstop); if (sstart=="") start=-1,stop=(int)sstop; else if (sstop=="") start=(int)sstart,stop=-1; else start=(int)sstart,stop=(int)sstop; break; case "jan": case "feb": case "mar": case "apr": case "may": case "jun": case "jul": case "aug": case "sep": case "oct": case "nov": case "dec": if (!names) names=allocate(366); sscanf(s,"%d%*[ ]%{%*[, ]%[^,]%}",int mday,array name); #if 1 if (mday<1 || mday>nd_m_nd[w]) error("Nameday date doesn't exists:\n%O\n",line); #endif
ca8d192001-01-01Mirar (Pontus Hagland)  if (sizeof(name))
dc29c62001-09-19Mirar (Pontus Hagland)  { name=`+(@name); if (decoder) name=map(name,decoder); names[nd_m_yd[w]+mday-1]=name; }
4f7b302000-09-30Mirar (Pontus Hagland)  break; case "leapday": sscanf(s,"%{%*[, ]%[^,]%}",name); names[365]=`+(@name); break; default: if (w[0]=='#') break; error("Unknown namedays definition statement:\n%O\n",line); } #endif } if (names) if (res) res|=new_namedays_object(region,id||"?", start,stop,leapdayshift,names); else res=new_namedays_object(region,id||"?",start,stop,leapdayshift,names); return res;
78fd532000-07-12Mirar (Pontus Hagland) }
68e10f2000-09-07Mirar (Pontus Hagland) Event.Event find_event(string s) { Event.Event e=loaded_events[s]; if (e) return e;
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  if (!all_data) read_all_data();
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  if (s[..8]=="namedays/") return find_namedays(s[9..]);
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  int i=search(all_data,sprintf("Event %O",s));
f2d7a62002-02-14Martin Nilsson  if (i==-1) return UNDEFINED;
41bb3a2000-08-01Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  int j=search(all_data,"\n",i); if (j==-1) j=0x7fffffff; return make_event(all_data[i..j]); }
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) Event.Event find_region(string c) { Event.Event e=loaded_events[c]; if (e) return e;
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  if (!all_data) read_all_data();
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  int i=search(all_data,sprintf("\nRegion %O",c));
f2d7a62002-02-14Martin Nilsson  if (i==-1) return UNDEFINED;
68e10f2000-09-07Mirar (Pontus Hagland)  int j=search(all_data,"\nRegion \"",i+1); if (j==-1) j=0x7fffffff;
78fd532000-07-12Mirar (Pontus Hagland) 
6a50d62003-02-27Henrik Grubbström (Grubba)  array(Event.Event) events=({}); mapping(Event.Event:multiset(string)) eflags=([]);
68e10f2000-09-07Mirar (Pontus Hagland)  mapping(string:multiset(string)) flagy=([]);
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  foreach ( (all_data[i..j]/"\n")[2..], string line) { string whut,id="",flags="-"; Event.Event e; if (sscanf(line,"%*[ \t]%[^ \t]%*[ \t]\"%s\"%*[ \t]%[-a-z]", whut,id,flags)>=4 && whut!="" && whut[0]!='#') switch (whut) { case "Add": e=find_event(id); if (!e) error("Events: Adding undefined event\n%O\n",line); if (flags!="-") eflags[e]=(flagy[flags]|| (flagy[flags]=mkmultiset( (flags-"-")/"" ))); events+=({e}); break; case "Event": e=make_event(line); if (flags!="-") eflags[e]=(flagy[flags]|| (flagy[flags]=mkmultiset( (flags-"-")/"" ))); events+=({e}); break; case "Include": e=find_region(id); if (!e) error("Events: Including undefined region %O\n%O\n",id,line); if (!e->is_superevent) error("Events: Including non-region %O\n%O\n",id,line); events|=e->events; if (flags=="-") eflags|=e->flags; else { multiset f1=(flagy[flags]|| (flagy[flags]=mkmultiset( (flags-"-")/"" ))); foreach (e->events, Event.Event e2) eflags[e2]=f1|(e->flags[e2] || (<>)); } break; case "Without": e=find_event(id); if (!e) error("Events: Removing undefined event\n%O\n",line); events-=({e}); m_delete(eflags,e); break; default: error("Events: Unknown region directive:\n%O\n",line); } } return loaded_regions[c]=Event.SuperEvent(events,eflags,c); }
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) array all_regions() { if (!all_data) read_all_data(); return `+(@array_sscanf(all_data,"%{%*s\nRegion \"%s\"%}")[0]); }
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) // -----------------------------------------------------------------------
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) program|Event.Event `[](string s) { return ::`[](s) || magic_event(s); } function `-> = `[];
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) // Don't load Geogrphy.Countries unless we have to object country_lookup=0;
78fd532000-07-12Mirar (Pontus Hagland) 
0332d82000-10-26Mirar (Pontus Hagland) Event.Event|Event.Namedays magic_event(string s)
68e10f2000-09-07Mirar (Pontus Hagland) { Event.Event e; if ( (e=loaded_events[s]) ) return e;
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  s=replace(s,"_"," ");
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  if (e=find_event(s)) return e; if (e=find_region(s)) return e;
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  if (!country_lookup) country_lookup=master()->resolv("Geography.Countries"); object c=country_lookup->from_name(s); if (c && (e=find_region(lower_case(c->iso2)))) return e;
0332d82000-10-26Mirar (Pontus Hagland)  if (s=="tzshift") return loaded_events->tzshift=Event.TZShift_Event();
78fd532000-07-12Mirar (Pontus Hagland) 
f2d7a62002-02-14Martin Nilsson  return UNDEFINED;
68e10f2000-09-07Mirar (Pontus Hagland) }
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) Event.SuperEvent country(string s) { s=replace(s,"_"," "); return find_region(s); }
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) Event.SuperEvent event(string s) { s=replace(s,"_"," "); return find_event(s); }
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland) mapping made_events=([]);
78fd532000-07-12Mirar (Pontus Hagland)