c3d8282000-09-26Fredrik Hübinette (Hubbe) #pike __VERSION__
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() { all_data=Stdio.read_bytes( 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); if (search(rule,"\"")!=-1)
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 if (sscanf(rule, "WDRel%*[ \t]%s%*[ \t]%s%*[ \t]%d%*[a-z]%*[ \t]%d days", mn,wd,n,days)>=5 && 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 if (sscanf(rule, "WDRel%*[ \t]%s%*[ \t]%s%*[ \t]%s%*[ \t]%d days", mn,wd,a,days)>=5 && a=="last" && (m=month2n[mn]) && wd2n[wd]) { m=(m%12)+1; Event.Event e= Event.Monthday_Weekday_Relative( id,s,1,month2n[mn],wd2n[wd],-1,0); e->nd=days; return e; } // WDRel May 17 Fri +17 excl if (sscanf(rule, "WDRel%*[ \t]%s%*[ \t]%d%*[ \t]%s%*[ \t]" "%s%*[ \t]%d%[ \t]%s%[ \t]%d days", mn,md,wd,n,a,days)>=7 && a=="excl" && (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; } // WDRel May 17 Fri +17 if (sscanf(rule, "WDRel%*[ \t]%s%*[ \t]%d%*[ \t]%s%*[ \t]" "%d%[ \t]%d days", mn,md,wd,n,days)>=7 && (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)  } }
68e10f2000-09-07Mirar (Pontus Hagland) Event.Event find_namedays(string s)
78fd532000-07-12Mirar (Pontus Hagland) {
68e10f2000-09-07Mirar (Pontus Hagland)  return Event.NullEvent(s,"?");
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)); if (i==-1) return ([])[0];
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)); if (i==-1) return ([])[0]; int j=search(all_data,"\nRegion \"",i+1); if (j==-1) j=0x7fffffff;
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  array(Event) events=({}); mapping(Event:multiset(string)) eflags=([]); 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) 
68e10f2000-09-07Mirar (Pontus Hagland) Event|Event.Namedays magic_event(string s) { 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;
78fd532000-07-12Mirar (Pontus Hagland) 
68e10f2000-09-07Mirar (Pontus Hagland)  return ([])[0]; }
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)