33 #include "holidayparserdriverplan_p.h" 
   34 #include "holidayscannerplan_p.h" 
   35 #include "holidayparserplan.hpp" 
   41 #include <KCalendarSystem> 
   44 #include "holiday_p.h" 
   51 using namespace KHolidays;
 
   55                         m_traceParsing( false ),
 
   56                         m_traceScanning( false ),
 
   57                         m_parseMetadataOnly( false )
 
   59     QFile holidayFile( filePath() );
 
   60     if ( holidayFile.
open( QIODevice::ReadOnly ) ) {
 
   61         m_scanData = holidayFile.
readAll();
 
   65     m_scanner->set_debug( m_traceScanning );
 
   68     m_fileToParse = 
new std::string( filePath().toLocal8Bit().data() );
 
   82   Q_UNUSED( errorLocation );
 
   85   kDebug() << errorMessage;
 
   90     kDebug() << errorMessage;
 
   97     foreach ( 
const QString &calendar, m_fileCalendarTypes ) {
 
  105         for ( m_parseYear = m_parseStartYear; m_parseYear <= m_parseEndYear; ++m_parseYear ) {
 
  107             m_parseCalendar->setDate( m_parseYearStart, m_parseYear, 1, 1 );
 
  108             m_parseYearEaster = easter( m_parseYear );
 
  109             m_parseYearPascha = pascha( m_parseYear );
 
  111             std::istringstream iss2( std::string( m_scanData.
data() ) );
 
  112             m_scanner->yyrestart( &iss2 );
 
  122     m_parseMetadataOnly = 
true;
 
  123     m_fileCountryCode.
clear();
 
  124     m_fileLanguageCode.
clear();
 
  126     m_fileDescription.
clear();
 
  127     m_fileCalendarTypes.
clear();
 
  133     std::istringstream iss2( std::string( m_scanData.
data() ) );
 
  134     m_scanner->yyrestart( &iss2 );
 
  136     m_resultList.
clear();
 
  145             if ( m_fileCountryCode.
isEmpty() ) {
 
  146                 setFileCountryCode( metadata[1].toUpper() );
 
  148             if ( m_fileLanguageCode.
isEmpty() ) {
 
  150                 m_fileLanguageCode = language[0];
 
  151                 if ( language.
count() > 1 ) {
 
  152                     setFileLanguageCode( language[0].append( 
QLatin1Char(
'_') ).append( language[1].toUpper() ) );
 
  154                   setFileLanguageCode( language[0] );
 
  157             if ( m_fileLanguageCode.
isEmpty() && metadata.
count() > 3 ) {
 
  158                 m_fileName = metadata[3];
 
  163     m_parseMetadataOnly = 
false;
 
  166 QString HolidayParserDriverPlan::filePath()
 
  171 std::string *HolidayParserDriverPlan::fileToParse()
 const 
  173     return m_fileToParse;
 
  181 int HolidayParserDriverPlan::adjustedMonthNumber( 
int month )
 
  184          m_parseCalendar->calendarType() != 
QLatin1String(
"hebrew") ||
 
  185          !m_parseCalendar->isLeapYear( m_parseYear ) ||  
 
  201 bool HolidayParserDriverPlan::isLeapYear( 
int year )
 
  203     return m_parseCalendar->isLeapYear( year );
 
  206 int HolidayParserDriverPlan::parseYear()
 
  211 int HolidayParserDriverPlan::monthsInYear( 
int year )
 
  214     m_parseCalendar->setDate( tempDate, year, 1, 1 );
 
  215     return m_parseCalendar->monthsInYear( tempDate );
 
  218 int HolidayParserDriverPlan::daysInMonth( 
int year, 
int month )
 
  221     m_parseCalendar->setDate( tempDate, year, month, 1 );
 
  222     return m_parseCalendar->daysInMonth( tempDate );
 
  225 int HolidayParserDriverPlan::julianDay( 
int year, 
int month, 
int day )
 
  228     m_parseCalendar->setDate( tempDate, year, month, day );
 
  232 void HolidayParserDriverPlan::julianDayToDate( 
int jd, 
int *year, 
int *month, 
int *day )
 
  237         *year = m_parseCalendar->year( tempDate );
 
  240         *month = m_parseCalendar->month( tempDate );
 
  243         *day = m_parseCalendar->day( tempDate );
 
  247 QDate HolidayParserDriverPlan::easter( 
int year )
 
  249     if ( m_parseCalendar->calendarType() != 
QLatin1String(
"gregorian") ) {
 
  257     int h = ( c - ( c / 4 ) - ( ( ( 8 * c ) + 13 ) / 25 ) + ( 19 * g ) + 15 ) % 30;
 
  258     int i = h - ( ( h / 28 ) * ( 1 - ( ( 29 / ( h + 1 ) ) * ( ( 21 - g ) / 11 ) ) ) );
 
  259     int j = ( year + ( year / 4 ) + i + 2 - c + ( c / 4 ) ) % 7;
 
  261     int month = 3 + ( ( l + 40 ) / 44 );
 
  262     int day = l + 28 - ( 31 * ( month / 4 ) );
 
  268 QDate HolidayParserDriverPlan::pascha( 
int year )
 
  270     if ( m_parseCalendar->calendarType() == 
QLatin1String(
"gregorian") ||
 
  271          m_parseCalendar->calendarType() == 
QLatin1String(
"julian") ) {
 
  276         int i = ( ( 19 * g ) + 15 ) % 30;
 
  277         int j = ( year + ( year / 4 ) + i ) % 7;
 
  279         int month = 3 + ( ( l + 40 ) / 44 );
 
  280         int day = l + 28 - ( 31 * ( month / 4 ) );
 
  282         if ( m_parseCalendar->calendarType() == 
QLatin1String(
"julian") ) {
 
  286         if ( m_parseCalendar->calendarType() == 
QLatin1String(
"gregorian") ) {
 
  288             int paschaJd = julianDay( year, month, day );
 
  303 int HolidayParserDriverPlan::julianDayFromEventName( 
const QString &eventName )
 
  305     foreach ( 
const KHolidays::Holiday &thisHoliday, m_resultList ) {
 
  306         if ( thisHoliday.text() == eventName ) {
 
  307             return thisHoliday.date().toJulianDay();
 
  314 int HolidayParserDriverPlan::julianDayFromEaster( 
void )
 
  325 int HolidayParserDriverPlan::julianDayFromPascha( 
void )
 
  336 int HolidayParserDriverPlan::julianDayFromMonthDay( 
int month, 
int day ) {
 
  337     return julianDay( m_parseYear, month, day );
 
  341 int HolidayParserDriverPlan::julianDayFromRelativeWeekday( 
int occurrence, 
int weekday, 
int jd )
 
  343     if ( occurrence == ANY ) {  
 
  351     if ( occurrence > 0 ) {
 
  352         occurrence = occurrence - 1;
 
  353     } 
else if ( occurrence < 0 && weekday == thisWeekday ) {
 
  354         occurrence = occurrence + 1;
 
  357     if ( weekday < thisWeekday ) {
 
  358         occurrence = occurrence + 1;
 
  361     return jd + weekday - thisWeekday + ( occurrence * 7 );
 
  365 int HolidayParserDriverPlan::julianDayFromWeekdayInMonth( 
int occurrence, 
int weekday, 
int month )
 
  367     if ( occurrence == LAST ) {  
 
  368         return julianDayFromRelativeWeekday( BEFORE, weekday, julianDay( m_parseYear, month, daysInMonth( m_parseYear, month ) ) );
 
  370         return julianDayFromRelativeWeekday( occurrence, weekday, julianDay( m_parseYear, month, 1 ) );
 
  379 void  HolidayParserDriverPlan::setFileCountryCode( 
const QString &countryCode )
 
  381     m_fileCountryCode = countryCode;
 
  384 void  HolidayParserDriverPlan::setFileLanguageCode( 
const QString &languageCode )
 
  386     m_fileLanguageCode = languageCode;
 
  389 void  HolidayParserDriverPlan::setFileName( 
const QString &name )
 
  394 void  HolidayParserDriverPlan::setFileDescription( 
const QString &description )
 
  396     m_fileDescription = description;
 
  399 void  HolidayParserDriverPlan::setEventName( 
const QString &eventName )
 
  402     m_eventCategories.
clear();
 
  403     m_eventName = eventName;
 
  406 void  HolidayParserDriverPlan::setEventCategory( 
const QString &category )
 
  408     m_eventCategories.
append( category );
 
  411 void  HolidayParserDriverPlan::setEventCalendarType( 
const QString &calendarType )
 
  413     m_eventCalendarType = calendarType;
 
  414     if ( m_parseMetadataOnly && !m_fileCalendarTypes.
contains( calendarType ) ) {
 
  415         m_fileCalendarTypes.
append( calendarType );
 
  419 void  HolidayParserDriverPlan::setEventDate( 
int eventYear, 
int eventMonth, 
int eventDay )
 
  421     m_eventYear = eventYear;
 
  422     m_eventMonth = eventMonth;
 
  423     m_eventDay = eventDay;
 
  426 void  HolidayParserDriverPlan::setEventDate( 
int jd )
 
  428     julianDayToDate( jd, &m_eventYear, &m_eventMonth, &m_eventDay );
 
  441 void HolidayParserDriverPlan::setFromWeekdayInMonth( 
int occurrence, 
int weekday, 
int month, 
int offset, 
int duration )
 
  444     if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
 
  448     int startMonth, endMonth;
 
  449     if ( month == LAST ) {
 
  450         startMonth = monthsInYear( m_parseYear );
 
  451         endMonth = startMonth;
 
  452     } 
else if ( month == ANY ) {
 
  454         endMonth = monthsInYear( m_parseYear );
 
  461     for ( 
int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
 
  463         if ( m_parseCalendar->isValid( m_parseYear, thisMonth, 1 ) ) {
 
  464             int startOccurrence, endOccurrence;
 
  465             if ( occurrence == ANY ) {  
 
  469                 startOccurrence = occurrence;
 
  470                 endOccurrence = occurrence;
 
  473             int jdMonthStart = julianDay( m_parseYear, thisMonth, 1 );
 
  474             int jdMonthEnd = julianDay( m_parseYear, thisMonth, daysInMonth( m_parseYear, thisMonth ) );
 
  477             for ( 
int thisOccurrence = startOccurrence; thisOccurrence <= endOccurrence; ++thisOccurrence ) {
 
  478                 int thisJd = julianDayFromWeekdayInMonth( thisOccurrence, weekday, thisMonth );
 
  479                 if ( thisJd >= jdMonthStart && thisJd <= jdMonthEnd ) {
 
  480                     setEvent( thisJd + offset, 0, duration );
 
  494 void HolidayParserDriverPlan::setFromRelativeWeekday( 
int occurrence, 
int weekday, 
int offset, 
int duration )
 
  497     if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
 
  502     if ( m_eventYear == ANY ) {  
 
  503         thisYear = m_parseYear;
 
  505         thisYear = m_eventYear;
 
  508     int startMonth, endMonth;
 
  509     if ( m_eventMonth == LAST ) {  
 
  510         startMonth = monthsInYear( thisYear );
 
  511         endMonth = startMonth;
 
  512     } 
else if ( m_eventMonth == ANY ) {  
 
  514         endMonth = monthsInYear( thisYear );
 
  516         startMonth = m_eventMonth;
 
  517         endMonth = m_eventMonth;
 
  522     for ( thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
 
  524         int startDay, endDay;
 
  525         if ( m_eventDay == LAST ) {  
 
  526             startDay = daysInMonth( thisYear, thisMonth );
 
  528         } 
else if ( m_eventDay == ANY ) {  
 
  530             endDay = daysInMonth( thisYear, thisMonth );
 
  532             startDay = m_eventDay;
 
  537         for ( 
int thisDay = startDay; thisDay <= endDay; ++thisDay ) {
 
  538             if ( m_parseCalendar->isValid( thisYear, thisMonth, thisDay ) ) {
 
  539                 int relativeJd = julianDayFromRelativeWeekday( occurrence, weekday, julianDay( thisYear, thisMonth, thisDay ) );
 
  540                 setEvent( relativeJd + offset, 0, duration );
 
  548 int HolidayParserDriverPlan::conditionalOffset( 
int year, 
int month, 
int day, 
int condition )
 
  558     m_parseCalendar->setDate( tempDate, year, month, day );
 
  559     int weekday = m_parseCalendar->dayOfWeek( tempDate );
 
  561     if ( condition & ( 1 << weekday ) ) {
 
  563         int to = ( condition >> 8 );
 
  564         while ( !( to & ( 1 << ( ( weekday + offset ) % 7 ) ) ) && ( offset < 8 ) ) {
 
  582 void HolidayParserDriverPlan::setFromDate( 
int offset, 
int condition, 
int duration )
 
  585     if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
 
  590     if ( m_eventYear == ANY ) {  
 
  591         thisYear = m_parseYear;
 
  593         thisYear = m_eventYear;
 
  596     int startMonth, endMonth;
 
  597     if ( m_eventMonth == LAST ) {  
 
  598         startMonth = monthsInYear( thisYear );
 
  599         endMonth = startMonth;
 
  600     } 
else if ( m_eventMonth == ANY ) {  
 
  602         endMonth = monthsInYear( thisYear );
 
  604         startMonth = m_eventMonth;
 
  605         endMonth = m_eventMonth;
 
  609     for ( 
int thisMonth = startMonth; thisMonth <= endMonth; ++thisMonth ) {
 
  611         int startDay, endDay;
 
  612         if ( m_eventDay == LAST ) {  
 
  613             startDay = daysInMonth( thisYear, thisMonth );
 
  615         } 
else if ( m_eventDay == ANY ) {  
 
  617             endDay = daysInMonth( thisYear, thisMonth );
 
  619             startDay = m_eventDay;
 
  624         for ( 
int thisDay = startDay; thisDay <= endDay; ++thisDay ) {
 
  626             if ( m_parseCalendar->isValid( thisYear, thisMonth, thisDay ) ) {
 
  627                 setEvent( julianDay( thisYear, thisMonth, thisDay ) + offset,
 
  628                           conditionalOffset( thisYear, thisMonth, thisDay, condition ), duration );
 
  642 void HolidayParserDriverPlan::setFromEaster( 
int offset, 
int duration )
 
  645     if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
 
  650         setEvent( m_parseYearEaster.
toJulianDay() + offset, 0, duration );
 
  662 void HolidayParserDriverPlan::setFromPascha( 
int offset, 
int duration )
 
  665     if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
 
  670         setEvent( m_parseYearPascha.
toJulianDay(), offset, duration );
 
  677 void HolidayParserDriverPlan::setEvent( 
int jd, 
int observeOffset, 
int duration )
 
  680     if ( m_parseMetadataOnly || m_eventCalendarType != m_parseCalendar->calendarType() ) {
 
  685     int observeJd = jd + observeOffset;
 
  687     if ( m_multidayMode == Holiday::MultidayHolidaysAsSingleEvents ) {
 
  691         for ( 
int dd = 0; dd < duration; ++dd ) {
 
  697 void  HolidayParserDriverPlan::addHoliday( 
const QDate &observedDate, 
int duration )
 
  700     if ( m_parseCalendar->isValid( observedDate ) &&
 
  701          observedDate <= m_requestEnd &&
 
  702          observedDate.
addDays( duration - 1 ) >= m_requestStart ) {
 
  703         KHolidays::Holiday holiday;
 
  704         holiday.d->mObservedDate = observedDate;
 
  705         holiday.d->mDuration = duration;
 
  706         holiday.d->mText = m_eventName;
 
  707         holiday.d->mShortText = m_eventName;
 
  708         if ( m_eventCategories.
contains( 
"public" ) ) {
 
  709             holiday.d->mDayType = KHolidays::Holiday::NonWorkday;
 
  711             holiday.d->mDayType = KHolidays::Holiday::Workday;
 
  713         m_resultList.
append( holiday );
 
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
 
bool contains(const QString &str, Qt::CaseSensitivity cs) const
 
virtual void setParseStartEnd()
Initialise parse year variables for calendar system. 
 
void error(const KHolidays::location &errorLocation, const QString &errorMessage)
Bison C++ skeleton error message handling. 
 
~HolidayParserDriverPlan()
Destructor. 
 
HolidayParserDriver abstract base class. 
 
HolidayScannerPlan implementation class. 
 
void set_debug_level(debug_level_type l)
Set the current debugging level. 
 
int count(const T &value) const
 
void append(const T &value)
 
void parseMetadata()
Parse the file for metadata only and populate the metadata variables. 
 
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
 
virtual int parse()
Parse. 
 
virtual void setParseCalendar(const QString &calendarType)
Set the calendar system to use. 
 
void parse()
Actually parse the file, new plan format implementation. 
 
QStringList split(const QString &sep, const QString &str, bool allowEmptyEntries)
 
QDate addDays(int ndays) const
 
QDate fromJulianDay(int jd)
 
HolidayParserDriverPlan(const QString &planFilename)
Constructor of Plan file parser driver.