/*

*  gcal_rcc.c:  Checks if a line (of a resource file) must be inserted into `rc_elems_table[]'.

*

*

*  Copyright (C) 1994, 1995, 1996 Thomas Esken

*

*  This software doesn't claim completeness, correctness or usability.

*  On principle I will not be liable for ANY damages or losses (implicit

*  or explicit), which result from using or handling my software.

*  If you use this software, you agree without any exception to this

*  agreement, which binds you LEGALLY !!

*

*  This program is free software; you can redistribute it and/or modify

*  it under the terms of the `GNU General Public License' as published by

*  the `Free Software Foundation'; either version 2, or (at your option)

*  any later version.

*

*  You should have received a copy of the `GNU General Public License'

*  along with this program; if not, write to the:

*

*    Free Software Foundation, Inc.

*    59 Temple Place - Suite 330

*    Boston, MA 02111-1307,  USA

*/







/*

*  Include definition header file to see whether USE_RC is defined there.

*    Compile this module only if USE_RC is defined, otherwise skip it.

*/

#include "gcal_tai.h"







#if USE_RC

#  ifdef RCSID

static char rcsid[]="$Id: gcal_rcc.c 2.01 1996/06/11 02:00:01 tom Exp $";

#  endif







/*

*  Include header files.

*/

#  if HAVE_CTYPE_H

#    include <ctype.h>

#  endif

#  include "gcal.h"







/*

*  Function prototypes.

*/

#  if __cplusplus

extern "C"

{

#  endif

/*

************************************************** Defined in `gcal_rc.c'.

*/

IMPORT Line_struct *

rc_get_date __P_((      char        *the_line,

                        Line_struct *lineptrs,

                  const Bool         is_rc_file,

                        Bool        *is_weekday_mode,

                        int         *d,

                        int         *m,

                        int         *y,

                        int         *n,

                        int         *len,

                        char        *hc,

                        int         *hn,

                        int         *hwd,

                  const char        *filename,

                  const long         line_number,

                  const char        *line_buffer,

                  const Bool         on_error_exit));

IMPORT Bool

precomp_nth_wd __P_((      int         diff,

                     const int         wd,

                           int        *n,

                           int        *day,

                           int        *month,

                           int        *year,

                     const Cmode_enum  mode));

IMPORT Bool

precomp_date __P_((      int         diff,

                   const int         wd,

                         int        *day,

                         int        *month,

                   const int         year,

                   const Cmode_enum  mode));

IMPORT void

nth_weekday_of_month __P_((      int  *d,

                                 int  *m,

                                 int  *y,

                           const int  *n,

                                 Bool *is_weekday_mode));

IMPORT void

prev_date __P_((int *day,

                int *month,

                int *year));

IMPORT void

next_date __P_((int *day,

                int *month,

                int *year));

IMPORT void

num2date __P_((Ulint  julian_days,

               int   *day,

               int   *month,

               int   *year));

IMPORT Slint

d_between __P_((const int d1,

                const int m1,

                const int y1,

                const int d2,

                const int m2,

                const int y2));

IMPORT Slint

w_between __P_((const int d1,

                const int m1,

                const int y1,

                const int d2,

                const int m2,

                const int y2));

IMPORT Slint

m_between __P_((const int m1,

                const int y1,

                const int m2,

                const int y2));

IMPORT void

manage_leap_day __P_((      int  *day,

                            int  *month,

                            int   year,

                      const char *line_buffer,

                      const char *filename,

                      const long  line_number));

/*

************************************************** Defined in `gcal_utl.c'.

*/

IMPORT VOID_PTR

my_malloc __P_((const int   amount,

                const int   exit_status,

                const char *module_name,

                const long  module_line,

                const char *var_name,

                const int   var_contents));

IMPORT VOID_PTR

my_realloc __P_((      VOID_PTR  ptr_memblock,

                 const int       amount,

                 const int       exit_status,

                 const char     *module_name,

                 const long      module_line,

                 const char     *var_name,

                 const int       var_contents));

IMPORT void

resize_all_strings __P_((const int   amount,

                         const char *module_name,

                         const long  module_line));

IMPORT void

my_error __P_((const int   exit_status,

               const char *module_name,

               const long  module_line,

               const char *var_name,

               const int   var_contents));

IMPORT int

compare_d_m_name __P_((const char       *string,

                       const Cmode_enum  mode));

IMPORT Bool

get_actual_date __P_((void));

IMPORT const char *

day_suffix __P_((int day));

IMPORT const char *

day_name __P_((const int day));

IMPORT const char *

short_month_name __P_((const int month));

IMPORT Ulint

date2num __P_((const int day,

               const int month,

               const int year));

IMPORT Bool

doy2date __P_((      int  doy,

               const int  is_leap_year,

                     int *day,

                     int *month));

IMPORT int

weekday_of_date __P_((const int day,

                      const int month,

                      const int year));

IMPORT int

day_of_year __P_((const int day,

                  const int month,

                  const int year));

IMPORT int

days_of_february __P_((const int year));

IMPORT Bool

valid_date __P_((const int day,

                 const int month,

                 const int year));

IMPORT int

week_number __P_((const int day,

                  const int month,

                  const int year));

IMPORT int

knuth_easter_formula __P_((const int year));

/*

************************************************** Defined in `gcal_rcc.c'.

*/

EXPORT void

rc_check __P_((      char *line_buffer,

               const char *filename,

               const long  line_number,

               const int   line_length,

                     int  *rc_elems,

               const int   day,

               const int   ed,

               const int   wd));

LOCAL Bool

date_matches_period __P_((      int *print_twice,

                                int  day,

                                int  ed,

                          const int  wd));

LOCAL void

insert_line_into_table __P_((      char *line_buffer,

                             const char *filename,

                             const long  line_number,

                                   int  *rc_elems,

                                   int   len_date,

                                   int   print_twice));

LOCAL int

get_number __P_((char **string));

#  if __cplusplus

}

#  endif







/*

*  Declare public(extern) variables.

*/

IMPORT const int    dvec[];                  /* Amount of days in months */

IMPORT Greg_struct *greg;                    /* Points to the used Gregorian Reformation date */

IMPORT Hls_struct   ehls1s;                  /* Effective hls 1 start (current day) */

IMPORT Hls_struct   ehls1e;                  /* Effective hls 1 end (current day) */

IMPORT Hls_struct   ehls2s;                  /* Effective hls 2 start (holiday) */

IMPORT Hls_struct   ehls2e;                  /* Effective hls 2 end (holiday) */

IMPORT Dvar_struct  rc_dvar[];               /* Date variables a[=`mmdd']...z[] (`yyyy'@{a|b|...|z}[[-]<n>]) */

IMPORT Line_struct *lineptrs;                /* Pointers to different parts of a (resource file) line */

IMPORT Line_struct *lptrs;                   /* Pointers to different parts of a (resource file) line */

IMPORT Line_struct *lptrs2;                  /* Pointers to different parts of a (resource file) line */

#ifdef DJG

IMPORT Usint        testval;                 /* Set to SHRT_MAX for checking the maximum table range */

#else

IMPORT Uint         testval;                 /* Set to INT_MAX for checking the maximum table range */

#endif

IMPORT Uint         maxlen_max;              /* Actual size of all string vectors */

IMPORT Uint         rc_elems_max;            /* Actual size of `rc_elems_table[]' */

IMPORT int          len_year_max;            /* String length of the maximum year able to compute */

IMPORT int          start_day;               /* -s1<0,1...7|day name> */

IMPORT int          month;                   /* Current month */

IMPORT int          year;                    /* Current year */

IMPORT int          rc_have_today_in_list;   /* [-c]d */

IMPORT int          act_min;                 /* Actual minute */

IMPORT int          act_hour;                /* Actual hour */

IMPORT int          act_day;                 /* Actual day */

IMPORT int          act_month;               /* Actual month */

IMPORT int          act_year;                /* Actual year */

IMPORT int          fiscal_month;            /* Starting month of a fiscal year */

IMPORT int          is_leap_year;            /* Is current year a leap year? */

IMPORT int          len_fil_wt;              /* Filler length of week number text */

IMPORT int          len_the_text;            /* Actual size of text buffer of "text-part" of a line */

IMPORT char        *the_text;                /* Text buffer of "text-part" of a line */

IMPORT char        *s1;                      /* General purpose text buffer */

IMPORT char        *s2;                      /* General purpose text buffer */

IMPORT char        *s6;                      /* General purpose text buffer */

IMPORT char       **rc_elems_table;          /* Stores the valid fixed date texts */

IMPORT Bool         rc_enable_fn_flag;       /* [-c]a */

IMPORT Bool         rc_weekno_flag;          /* [-c]k */

IMPORT Bool         rc_period_list;          /* [-c]l */

IMPORT Bool         rc_period_flag;          /* [-c]<<<<n>>[<d|w|+|-]>|`mmdd'|`mmww[w]'<n>> */

IMPORT Bool         rc_tomorrow_flag;        /* [-c]t */

IMPORT Bool         rc_week_flag;            /* [-c]w */

IMPORT Bool         rc_month_flag;           /* [-c]m */

IMPORT Bool         rc_year_flag;            /* [-c]y */

IMPORT Bool         rc_week_year_flag;       /* [-c<<n>>]w */

IMPORT Bool         rc_forwards_flag;        /* [-c<<n>|w|m|y>]+ */

IMPORT Bool         rc_backwards_flag;       /* [-c<<n>|w|m|y>]- */

IMPORT Bool         use_day_suffix;          /* Day suffix format specifier given in date format? */

IMPORT Bool         is_date_given;           /* Is a command (explicit date) given in the command line? */

IMPORT Bool         highlight_flag;          /* -H<yes> or -H<no> */

IMPORT Bool         is_3month_mode;          /* Argument is "." or ".+" or ".-" */

IMPORT Bool         is_3month_mode2;         /* Argument is ".." -> current quarter of actual year */

IMPORT Bool         adate_set;               /* [-c]<n>w and actual date modified */







/*

*  Define local(static) variables.

*/

LOCAL int   incr_year;         /* Indicates whether event appears in next year too */

LOCAL int   decr_year;         /* Indicates whether event appears in previous year too */

LOCAL int   d;                 /* Day of event found in line */

LOCAL int   m;                 /* Month of event found in line */

LOCAL int   y;                 /* Year of event found in line */

LOCAL int   d_buf;             /* Buffered day of event */

LOCAL int   m_buf;             /* Buffered month of event */

LOCAL int   hn;                /* The `N'th weekday of month' displacement value */

LOCAL int   hwd;               /* The weekday number of `N'th weekday of month'*/

LOCAL char  hc;                /* The mode specifying character */

LOCAL Bool  is_2dvar;          /* Reference to a date variable found in line */

LOCAL Bool  is_2easter;        /* Reference to Easter Sundays date found in line */

LOCAL Bool  is_weekday_mode;   /* Textual weekday name is found and must be respected */

LOCAL Bool  changed_month;     /* No explicit month command is given in the command line */







   PUBLIC void

rc_check (line_buffer, filename, line_number, line_length, rc_elems, day, ed, wd)

         char *line_buffer;

   const char *filename;

   const long  line_number;

   const int   line_length;

         int  *rc_elems;

   const int   day;

   const int   ed;

   const int   wd;

/*

   Checks whether a single line of a resource file resp., eternal holiday must be displayed.

*/

{

   register int  i;

   register int  j;

   register int  buf_d=0;

   register int  buf_m;

   register int  buf_y;

   register int  dvar_base_day=0;

   register int  dvar_base_month=0;

   register int  repeat=0;

   register int  appears=0;

   register int  productions=2;

   register int  tmp_month=month;

   auto     int  print_twice;

   auto     int  len_date;

   auto     int  n;

   auto     int  tmp_d;

   auto     int  tmp_m;

   auto     int  tmp_y;

   auto     int  tmp_n;

   auto     int  tmp_hn;

   auto     int  tmp_hwd=0;

   auto     Bool is_valid_date;

   auto     Bool is_day_given;

   auto     Bool is_month_given;

   auto     Bool is_coded_month;

   auto     Bool is_first=TRUE;

   auto     Bool is_range=FALSE;

   auto     Bool date_unset=FALSE;

   auto     Bool must_ignore_feb_29=FALSE;





   /*

      Decode a delivered line:

        This means all necessary information is stored in the according

        variables, which are set by decoding the "date"-part of the line.

   */

   lineptrs = rc_get_date (line_buffer, lineptrs, TRUE, &is_weekday_mode, &d, &m, &y, &n, &len_date,

                           &hc, &hn, &hwd, filename, line_number, line_buffer, TRUE);

   if (len_date < 1)

     /*

        Error, invalid date field given.

     */

     my_error (123, filename, line_number, line_buffer, 0);

   if (   (len_date < line_length)

       && !*lineptrs->text_part)

     /*

        Error, missing whitespace character between "date"-part and "text"-part.

     */

     my_error (116, filename, line_number, line_buffer, 0);

   if (!month)

    {

      month = act_month;

      changed_month = TRUE;

    }

   else

     changed_month = FALSE;

   buf_m = m;

   buf_y = y;

   /*

      We work with a buffer of the returned (allocated and filled)

        char pointers of the `lineptrs' struct.

   */

   lptrs->day_part = lineptrs->day_part;

   lptrs->repeat_part = lineptrs->repeat_part;

   lptrs->appears_part = lineptrs->appears_part;

   do

    {

      /*

         Look if a list/range of days/weekday names is given,

           if so then let's create 1xN productions of such a line.

      */

      if (   !is_range

          && (lptrs->day_part != (char *)NULL))

       {

         auto char  *ptr2_char;

         auto char   ch;





         repeat=appears=hwd=tmp_hn=hn=tmp_n=n=i = 0;

         is_range=is_coded_month=is_month_given=is_day_given=is_weekday_mode = FALSE;

         /*

            Store the base date if a date variable is given.

         */

         if (   is_first

             && islower(hc))

          {

            if (y == -1)

              /*

                 Error, date variable is undefined.

              */

              break;

            dvar_base_day = d;

            dvar_base_month = m;

          }

         if (lineptrs->day_list)

          /*

             Manage a list of days/weekday names.

          */

          {

            /*

               If a list of days/weekday names is given, we have to set the

                 number of productions to any value greater 1, because we

                 terminate the production creating loop by a `break' statement

                 after all elements of the list are evaluated.

            */

            productions = 2;

            /*

               Copy an element of the list into `s6'.

            */

            while (   *lptrs->day_part

                   && !isspace(*lptrs->day_part)

                   && (*lptrs->day_part != RC_DLIST_CHAR

                   && (*lptrs->day_part != RC_REPEAT_CHAR)

                   && (*lptrs->day_part != RC_APPEARS_CHAR)))

              s6[i++] = *(lptrs->day_part++);

            s6[i] = '\0';

            if (   !i

                && (   !is_first

                    || !islower(hc)))

              /*

                 Error, an empty list element given (e.g.:  dd,,dd or ww[w],,ww[w]N)

                   the only place where an empty list element may occur is

                   the trailing character after a @`dvar'|e text, e.g.:  @e,+10,-3fr ...,

                   which means -> first evaluate  @e  and then  @e+10  and then  @e-3fr.

              */

              my_error (123, filename, line_number, line_buffer, 0);

            is_first = FALSE;

            ptr2_char = s6;

            if (   hc

                && *ptr2_char)

             {

               hn = atoi(s6);

               if (islower(hc))

                {

                  if (   *ptr2_char == *ASC_LIT

                      || *ptr2_char == *DES_LIT)

                    ptr2_char++;

                  if (   *ptr2_char == *ASC_LIT

                      || *ptr2_char == *DES_LIT

                      || isalpha(*ptr2_char))

                    /*

                       Error, simple weekday name or invalid sign given.

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

               else

                 if (   *ptr2_char == *ASC_LIT

                     || *ptr2_char == *DES_LIT)

                   /*

                      Error, invalid sign given.

                   */

                   my_error (123, filename, line_number, line_buffer, 0);

               /*

                  Now eat all digits.

               */

               while (isdigit(*ptr2_char))

                 ptr2_char++;

             }

            if (   !hc

                || *ptr2_char)

             {

               if (   !hc

                   && i)

                {

                  if (i > 2)

                   {

                     if (!isdigit(*ptr2_char))

                      {

                        ch = s6[TXTLEN_MONTH];

                        s6[TXTLEN_MONTH] = '\0';

                        m = compare_d_m_name (ptr2_char, MOnth);

                        s6[TXTLEN_MONTH] = ch;

                        if (!m)

                         {

                           if (compare_d_m_name (ptr2_char, DAy))

                             goto LABEL_list_day_name_given;

                           /*

                              Error, invalid textual month name given.

                           */

                           my_error (123, filename, line_number, line_buffer, 0);

                         }

                        ptr2_char++;

                      }

                     else

                      {

                        ch = s6[2];

                        s6[2] = '\0';

                        m = atoi(ptr2_char);

                        if (m == 99)

                          m = MONTH_MAX;

                        if (m > MONTH_MAX)

                          /*

                             Error, invalid month number (mm) given.

                          */

                          my_error (123, filename, line_number, line_buffer, 0);

                        s6[2] = ch;

                      }

                     ptr2_char += 2;

                     if (m)

                       is_month_given = TRUE;

                     else

                       is_coded_month = TRUE;

                   }

LABEL_list_day_name_given:

                  d = atoi(ptr2_char);

                  if (d)

                    is_day_given = TRUE;

                  else

                    if (isdigit(*ptr2_char))

                      /*

                         Error, invalid day number (dd) given.

                      */

                      my_error (123, filename, line_number, line_buffer, 0);

                }

               if (!isdigit(*ptr2_char))

                {

                  d = compare_d_m_name (ptr2_char, DAy);

                  if (!d)

                    /*

                       Error, invalid textual day name (ww[w]) given.

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

             }

            if (   !is_month_given

                && !is_coded_month)

              m = buf_m;

            y = buf_y;

            if (!is_day_given)

             {

               if (!hc)

                {

                  if (isdigit(s6[i-1]))

                   {

                     if (isdigit(s6[i-2]))

                       /*

                          Error, "n'th weekday of month" field contains more than one digit.

                       */

                       my_error (123, filename, line_number, line_buffer, 0);

                     n = (s6[i-1] - '0');

                     /*

                        Error, invalid "n'th weekday of month" number given.

                     */

                     if (   (n > 5)

                         && (n < 9))

                       my_error (117, filename, line_number, line_buffer, n);

                   }

                  if (!n)

                    is_weekday_mode = TRUE;

                }

               else

                {

                  if (*ptr2_char)

                    hwd = d;

                  if (!islower(hc))

                    d = 0;

                }

             }

            if (islower(hc))

             {

               d = dvar_base_day;

               m = dvar_base_month;

             }

            if (   hc

                && y)

             {

               if (islower(hc))

                {

                  if (!precomp_date (hn, hwd, &d, &m, y,

                                     (hc == RC_EASTER_CHAR) ? EAster : DVar))

                    /*

                       If the date is uncomputable, skip this list entry.

                    */

                    y = -1;

                }

               else

                 if (!precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,

                                      (hc == 'D') ? DAy : WEek))

                   /*

                      If the date is uncomputable, skip this list entry.

                   */

                   y = -1;

             }

            if (   !y

                && !is_coded_month)

              manage_leap_day (&d, &m, year, line_buffer, filename, line_number);

            /*

               Check if a "repeat for N days since..." field or a

                 "for each N'th day since..." field is given in this list element.

            */

            if (   *lptrs->day_part == RC_REPEAT_CHAR

                || *lptrs->day_part == RC_APPEARS_CHAR)

             {

               if (is_weekday_mode)

                 /*

                    Error, it's invalid to specify a simple weekday name

                      with an "repeat" or "appears" coding (e.g.: www:10,www.3,www:10.3 ...).

                 */

                 my_error (123, filename, line_number, line_buffer, 0);

               else

                {

                  register int  num_repeat=0;

                  register int  num_appears=0;





                  do

                   {

                     if (*lptrs->day_part == RC_REPEAT_CHAR)

                      {

                        repeat = get_number (&lptrs->day_part);

                        num_repeat++;

                      }

                     if (*lptrs->day_part == RC_APPEARS_CHAR)

                      {

                        appears = get_number (&lptrs->day_part);

                        num_appears++;

                      }

                   } while (--productions);   /* I don't like the GNU-coding scheme for do-whiles */

                  if (   num_repeat > 1

                      || num_appears > 1

                      || (   !repeat

                          && !appears))

                    /*

                       Error, either "repeat" or "appears" coding given twice

                         or invalid by other reasons (a number > 999 given).

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                  if (appears)

                    appears--;

                  /*

                     Well, we have to use an unoptimized number of productions now.

                  */

                  productions = repeat;

                }

             }

            /*

               Skip the ONE separating character of the list of days.

            */

            if (*lptrs->day_part == RC_DLIST_CHAR)

              lptrs->day_part++;

            else

              if (   !*lptrs->day_part

                  || isspace(*lptrs->day_part))

               {

                 free(lineptrs->day_part);

                 lptrs->day_part=lineptrs->day_part = (char *)NULL;

               }

              else

                /*

                   Error, invalid "repeat" or "appears" coding given

                     (one of the fields contains invalid characters).

                */

                my_error (123, filename, line_number, line_buffer, 0);

          }

         else

          /*

             Manage a range of days/weekday names.

          */

          {

            if (lptrs->repeat_part != (char *)NULL)

              /*

                 Error, an "repeat" coding makes no sense in ranges of days.

              */

              my_error (123, filename, line_number, line_buffer, 0);

            /*

               Copy the starting element of the range into `s6'.

            */

            while (*lptrs->day_part != RC_DRANGE_CHAR)

              s6[i++] = *(lptrs->day_part++);

            s6[i] = '\0';

            if (strchr(s6, RC_APPEARS_CHAR) != (char *)NULL)

              /*

                 Error, a "appears" coding may only be given last to a range of days.

              */

              my_error (123, filename, line_number, line_buffer, 0);

            ptr2_char = s6;

            /*

               Skip THE separating character of the range of days.

            */

            lptrs->day_part++;

            if (   hc

                && *ptr2_char)

             {

               hn = atoi(s6);

               if (islower(hc))

                {

                  if (   *ptr2_char == *ASC_LIT

                      || *ptr2_char == *DES_LIT)

                    ptr2_char++;

                  if (   *ptr2_char == *ASC_LIT

                      || *ptr2_char == *DES_LIT

                      || isalpha(*ptr2_char))

                    /*

                       Error, simple weekday name or invalid sign given.

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

               else

                 if (   *ptr2_char == *ASC_LIT

                     || *ptr2_char == *DES_LIT)

                   /*

                      Error, invalid sign given.

                   */

                   my_error (123, filename, line_number, line_buffer, 0);

               /*

                  Now eat all digits.

               */

               while (isdigit(*ptr2_char))

                 ptr2_char++;

             }

            if (   !hc

                || *ptr2_char)

             {

               if (!hc)

                {

                  d = atoi(ptr2_char);

                  if (d)

                    is_day_given = TRUE;

                  else

                    if (isdigit(*ptr2_char))

                      /*

                         Error, invalid day number (== 0) given.

                      */

                      my_error (123, filename, line_number, line_buffer, 0);

                }

               if (!isdigit(*ptr2_char))

                {

                  buf_d=d = compare_d_m_name (ptr2_char, DAy);

                  if (!d)

                    /*

                       Error, invalid textual day name (ww[w]) given.

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

               if (!is_day_given)

                {

                  if (   !hc

                      && isdigit(s6[i-1]))

                   {

                     if (isdigit(s6[i-2]))

                       /*

                          Error, "n'th weekday of month" field contains more than one digit.

                       */

                       my_error (123, filename, line_number, line_buffer, 0);

                     n = (s6[i-1] - '0');

                     /*

                        Error, invalid "n'th weekday of month" number given.

                     */

                     if (   (n > 5)

                         && (n < 9))

                       my_error (117, filename, line_number, line_buffer, n);

                     if (n)

                      {

                        is_range = TRUE;

                        nth_weekday_of_month (&d, &m, &y, &n, &is_weekday_mode);

                        if (   !m

                            || y == -1)

                          /*

                             If the date is uncomputable, exit the loop.

                          */

                          break;

                      }

                     else

                       is_weekday_mode = TRUE;

                   }

                  else

                   {

                     if (!hc)

                       is_weekday_mode = TRUE;

                     else

                      {

                        is_range = TRUE;

                        hwd = d;

                      }

                   }

                }

               else

                {

                  if (   !m

                      && (   rc_year_flag

                          || rc_period_list

                          || is_3month_mode

                          || is_3month_mode2

                          || fiscal_month > MONTH_MIN))

                    /*

                       If no month `m' is given and we are in one of these modes,

                         exit the loop.

                    */

                    break;

                  is_range = TRUE;

                  if (!y)

                    y = year;

                  if (!m)

                    m = month;

                }

             }

            else

             {

               is_range = TRUE;

               hwd = 0;

             }

            if (hc)

             {

               if (!y)

                 y = year;

               if (islower(hc))

                {

                  d = dvar_base_day;

                  m = dvar_base_month;

                  if (!precomp_date (hn, hwd, &d, &m, y,

                                     (hc == RC_EASTER_CHAR) ? EAster : DVar))

                    date_unset = TRUE;

                }

               else

                 if (!precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,

                                      (hc == 'D') ? DAy : WEek))

                   date_unset = TRUE;

               if (date_unset)

                {

                  /*

                     If the date is uncomputable, set `d' and `m'

                       to 1-JAN if `hn' is less zero, otherwise to 31-DEC

                       if `hn' is greater than +1.

                  */

                  if (   !hn

                      || hwd)

                    /*

                       If the date is really uncomputable, exit the loop.

                    */

                    break;

                  date_unset = FALSE;

                  if (hn < 0)

                   {

                     m = MONTH_MIN;

                     d = DAY_MIN;

                   }

                  else

                   {

                     m = MONTH_MAX;

                     d = dvec[m-1];

                   }

                }

             }

            /*

               Copy the final element of the range into `s6'.

            */

            is_day_given = FALSE;

            i = 0;

            while (   *lptrs->day_part

                   && !isspace(*lptrs->day_part)

                   && (*lptrs->day_part != RC_APPEARS_CHAR))

              s6[i++] = *(lptrs->day_part++);

            s6[i] = '\0';

            ptr2_char = s6;

            free(lineptrs->day_part);

            lptrs->day_part=lineptrs->day_part = (char *)NULL;

            if (   hc

                && *ptr2_char)

             {

               tmp_hn = atoi(s6);

               if (islower(hc))

                {

                  if (   *ptr2_char == *ASC_LIT

                      || *ptr2_char == *DES_LIT)

                    ptr2_char++;

                  if (   *ptr2_char == *ASC_LIT

                      || *ptr2_char == *DES_LIT

                      || isalpha(*ptr2_char))

                    /*

                       Error, simple weekday name or invalid sign given.

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

               else

                 if (   *ptr2_char == *ASC_LIT

                     || *ptr2_char == *DES_LIT)

                   /*

                      Error, invalid sign given.

                   */

                   my_error (123, filename, line_number, line_buffer, 0);

               /*

                  Now eat all digits.

               */

               while (isdigit(*ptr2_char))

                 ptr2_char++;

               /*

                  Now eat an "appears" field (if given).

               */

               if (*ptr2_char == RC_APPEARS_CHAR)

                {

                  ptr2_char++;

                  while (isdigit(*ptr2_char))

                    ptr2_char++;

                }

             }

            if (   !hc

                || *ptr2_char)

             {

               if (   !hc

                   && i)

                {

                  if (i > 2)

                   {

                     if (!isdigit(*ptr2_char))

                      {

                        ch = s6[TXTLEN_MONTH];

                        s6[TXTLEN_MONTH] = '\0';

                        tmp_m = compare_d_m_name (ptr2_char, MOnth);

                        s6[TXTLEN_MONTH] = ch;

                        if (!tmp_m)

                         {

                           if (compare_d_m_name (ptr2_char, DAy))

                             goto LABEL_range_day_name_given;

                           /*

                              Error, invalid textual month name given.

                           */

                           my_error (123, filename, line_number, line_buffer, 0);

                         }

                        s6[3] = ch;

                        ptr2_char++;

                      }

                     else

                      {

                        ch = s6[2];

                        s6[2] = '\0';

                        tmp_m = atoi(ptr2_char);

                        if (tmp_m == 99)

                          tmp_m = MONTH_MAX;

                        if (tmp_m > MONTH_MAX)

                          /*

                             Error, invalid month number (mm) given.

                          */

                          my_error (123, filename, line_number, line_buffer, 0);

                        s6[2] = ch;

                      }

                     ptr2_char += 2;

                     if (tmp_m)

                       is_month_given = TRUE;

                     else

                       is_coded_month = TRUE;

                   }

LABEL_range_day_name_given:

                  tmp_d = atoi(ptr2_char);

                  if (tmp_d)

                    is_day_given = TRUE;

                }

               if (!isdigit(*ptr2_char))

                {

                  buf_d=tmp_d = compare_d_m_name (ptr2_char, DAy);

                  if (!tmp_d)

                    /*

                       Error, invalid textual day name (ww[w]) given.

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

               if (!is_day_given)

                {

                  if (isdigit(s6[i-1]))

                   {

                     if (isdigit(s6[i-2]))

                       /*

                          Error, "n'th weekday of month" field contains more than one digit.

                       */

                       my_error (123, filename, line_number, line_buffer, 0);

                     tmp_n = (s6[i-1] - '0');

                   }

                  if (   !hc

                      && tmp_n

                      && is_range)

                   {

                     /*

                        Error, invalid "n'th weekday of month" number given.

                     */

                     if (   (tmp_n > 5)

                         && (tmp_n < 9))

                       my_error (117, filename, line_number, line_buffer, tmp_n);

                     if (!is_month_given)

                       tmp_m = buf_m;

                     tmp_y = buf_y;

                     nth_weekday_of_month (&tmp_d, &tmp_m, &tmp_y, &tmp_n, &is_weekday_mode);

                     if (   !tmp_m

                         || tmp_y == -1)

                       /*

                          If the date is uncomputable, exit the loop.

                       */

                       break;

                     if (y != tmp_y)

                       /*

                          If the dates are in different years, exit the loop.

                       */

                       break;

                   }

                  else

                   {

                     if (   !hc

                         && (   tmp_n

                             || is_range))

                       /*

                          Error, mixed range of days given (dd#ww[w], ww[w]#ww[w]N or ww[w]N#www[w]).

                       */

                       my_error (123, filename, line_number, line_buffer, 0);

                     else

                       if (   !tmp_hn

                           && is_range)

                         /*

                            Error, invalid range of days given (Nww[w]#www[w]).

                         */

                         my_error (123, filename, line_number, line_buffer, 0);

                       else

                         tmp_hwd = tmp_d;

                   }

                }

               else

                {

                  if (   is_day_given

                      && !is_range)

                    /*

                       Error, invalid range of days given (ww[w]#dd).

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                  if (   !tmp_m

                      && is_coded_month

                      && (   rc_year_flag

                          || rc_period_list

                          || is_3month_mode

                          || is_3month_mode2

                          || fiscal_month > MONTH_MIN))

                    /*

                       If the month of a final day is coded like: ...#mmdd

                         or ...#mmww[w]N, but mm is explicitly set to zero (== 00 coded)

                         and we are in one of these modes, exit the loop.

                    */

                    break;

                  if (!is_month_given)

                    tmp_m = m;

                  tmp_y = y;

                }

             }

            else

              tmp_hwd = 0;

            /*

               We have to avoid constructions like: yyyy00dd|ww[w]N#mmdd|ww[w]N

                 which means, no starting month but a final month is given and

                 if both months differ after pre-evaluating the starting month

                 (which is set to the current month), exit the loop.

            */

            if (   !buf_m

                && is_month_given

                && (m != tmp_m))

              break;

            if (hc)

             {

               tmp_y = y;

               if (islower(hc))

                {

                  tmp_d = dvar_base_day;

                  tmp_m = dvar_base_month;

                  if (!precomp_date (tmp_hn, tmp_hwd, &tmp_d, &tmp_m, tmp_y,

                                     (hc == RC_EASTER_CHAR) ? EAster : DVar))

                    date_unset = TRUE;

                }

               else

                 if (!precomp_nth_wd (tmp_hn, tmp_hwd, &tmp_hn, &tmp_d, &tmp_m, &tmp_y,

                                      (hc == 'D') ? DAy : WEek))

                   date_unset = TRUE;

               if (date_unset)

                {

                  /*

                     If the date is uncomputable, set `tmp_d' and `tmp_m'

                       to 1-JAN if `tmp_hn' is less zero, otherwise to 31-DEC

                       if `tmp_hn' is greater than +1.

                  */

                  if (   !tmp_hn

                      || tmp_hwd)

                    /*

                       If the date is really uncomputable, exit the loop.

                    */

                    break;

                  if (tmp_hn < 0)

                   {

                     tmp_m = MONTH_MIN;

                     tmp_d = DAY_MIN;

                   }

                  else

                   {

                     tmp_m = MONTH_MAX;

                     tmp_d = dvec[tmp_m-1];

                   }

                }

               hc = '\0';

             }

            n = 0;

            /*

               Let's decode the "for each N'th day since..." field of a line.

            */

            if (lptrs->appears_part != (char *)NULL)

             {

               appears = get_number (&lptrs->appears_part);

               if (   !appears

                   || (   *lptrs->appears_part

                       && !isspace(*lptrs->appears_part)))

                 /*

                    Error, invalid "appears" field given.

                 */

                 my_error (123, filename, line_number, line_buffer, 0);

               appears--;

             }

            /*

               Compute the number of 1xN productions.

            */

            if (is_range)

             {

               /*

                  If the special value "99" for a day is given,

                    set the day to the last day of the month.

               */

               if (d == 99)

                {

                  if (m == 2)

                    d = days_of_february (y);

                  else

                    d = dvec[m-1];

                }

               if (tmp_d == 99)

                {

                  if (tmp_m == 2)

                    tmp_d = days_of_february (tmp_y);

                  else

                    tmp_d = dvec[tmp_m-1];

                }

               if (   d > 31

                   || tmp_d > 31)

                 /*

                    Error, invalid day number (>31) is given.

                 */

                 my_error (123, filename, line_number, line_buffer, 0);

               if (!buf_y)

                {

                  if (buf_m)

                    manage_leap_day (&d, &m, y, line_buffer, filename, line_number);

                  if (   is_month_given

                      || (   buf_m

                          && !is_month_given))

                    manage_leap_day (&tmp_d, &tmp_m, tmp_y, line_buffer, filename, line_number);

                  /*

                     Check if a range of days starting or ending at

                       00000229 must be ignored in non-leap years.

                  */

                  if (   (days_of_february (y) == 28)

                      && (   (   (d == 29)

                              && (m == 2)

                              && (m == buf_m))

                          || (   (tmp_d == 29)

                              && (tmp_m == 2)

                              && (   tmp_m == buf_m

                                  || is_month_given))))

                    must_ignore_feb_29 = TRUE;

                }

               /*

                  If invalid dates are given, try to correct them.

               */

               while (!valid_date (d, m, y))

                {

                  if (   !buf_m

                      || must_ignore_feb_29)

                    d--;

                  else

                    /*

                       Error, invalid date given (e.g.: yyyy0230 or yyyy0931).

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

               while (!valid_date (tmp_d, tmp_m, tmp_y))

                {

                  if (   (   !buf_m

                          && !is_month_given)

                      || must_ignore_feb_29)

                    tmp_d--;

                  else

                    /*

                       Error, invalid date given (e.g.: yyyy0230 or yyyy0931).

                    */

                    my_error (123, filename, line_number, line_buffer, 0);

                }

               /*

                  Compute the raw number of 1xN productions.

               */

               i = day_of_year (d, m, y);

               j = day_of_year (tmp_d, tmp_m, tmp_y);

               if (i > j)

                {

                  /*

                     Swap the starting date of the event.

                  */

                  i ^= (j ^= (i ^= j));

                  d = tmp_d;

                  m = tmp_m;

                  y = tmp_y;

                }

               productions = j - i;

               if (productions)

                {

                  /*

                     Optimize the number of 1xN productions.

                  */

                  if (i < day)

                   {

                     if (appears)

                      {

                        register int  k=i;





                        /*

                           Advance to the first date in period if an "appears" coding is given.

                        */

                        do

                         {

                           (void)doy2date (i+appears+1, (days_of_february (y)==29), &d, &m);

                           i = day_of_year (d, m, y);

                           if (i == k)

                             /*

                                The date can't be advanced by an "appears" factor

                                  because the computed date is would be off the year bounds!

                             */

                             i = day;

                         } while (i < day);   /* I don't like the GNU-coding scheme for do-whiles */

                      }

                     else

                       i = day;

                   }

                  /*

                     Set a new starting date of the event.

                  */

                  (void)doy2date (i, (days_of_february (y)==29), &d, &m);

                  if (j > ed - 1)

                    j = ed - 1;

                  productions = j - i;

                  if (productions < 0)

                    /*

                       Date doesn't match the warning period, exit the loop.

                    */

                    break;

                }

             }

            else

             {

               if (is_month_given)

                 /*

                    Error, simple textual weekday ranges (ww[w]#ww[w]) may

                      not have a specified final month like: ww[w]#mmww[w].

                 */

                 my_error (123, filename, line_number, line_buffer, 0);

               /*

                  Compute the number of 1xN productions for simple weekdays!

               */

               if (d > tmp_d)

                 productions = DAY_MAX - d + tmp_d;

               else

                 productions = tmp_d - d;

               buf_d = d;

             }

            productions++;

            is_first = FALSE;

          }

       }

      else

        if (is_first)

         {

           /*

              Single date given (means no list of days AND no range of days).

           */

           if (!y)

             manage_leap_day (&d, &m, year, line_buffer, filename, line_number);

           /*

              Let's decode the "repeat for N days since..." field of a line

                and/or the "for each N'th day since..." field of a line.

           */

           if (   lptrs->repeat_part != (char *)NULL

               || lptrs->appears_part != (char *)NULL)

            {

              if (   is_weekday_mode

                  && !n)

                /*

                   Error, "repeat" or "appears" coding given to a

                     simple weekday name (e.g.: yyyymmwww:10.3 ...).

                */

                my_error (123, filename, line_number, line_buffer, 0);

              if (lptrs->repeat_part != (char *)NULL)

               {

                 repeat = get_number (&lptrs->repeat_part);

                 if (   !repeat

                     || (   *lptrs->repeat_part

                         && !isspace(*lptrs->repeat_part)

                         && (*lptrs->repeat_part != RC_APPEARS_CHAR)))

                   /*

                      Error, invalid "repeat" field given.

                   */

                   my_error (123, filename, line_number, line_buffer, 0);

               }

              if (lptrs->appears_part != (char *)NULL)

               {

                 appears = get_number (&lptrs->appears_part);

                 if (   !appears

                     || (   *lptrs->appears_part

                         && !isspace(*lptrs->appears_part)

                         && (*lptrs->appears_part != RC_REPEAT_CHAR)))

                   /*

                      Error, invalid "appears" field given.

                   */

                   my_error (123, filename, line_number, line_buffer, 0);

               }

            }

           if (!repeat)

             /*

                Let's create either 1x1 or 1x2 productions of such a line by default.

             */

             productions = 1;

           else

            {

              /*

                 Now we have the number of productions of this date!

              */

              is_first = FALSE;

              if (appears)

                appears--;

              /*

                 Well, we have to use an unoptimized number of productions

                   in this case.

              */

              productions = repeat;

            }

         }

      /*

         If the "date"-part of the current line is valid,

           try to respect the current line.

      */

      if (y >= 0)

       {

         /*

            Necessary pre-initializations of module local variables.

         */

         is_valid_date = TRUE;

         is_2dvar=is_2easter = FALSE;

         incr_year=decr_year=d_buf=m_buf = 0;

         /*

            Default is a 1x1 production of a line

              (except some cases the -c[...]t "tomorrow" flag is given).

         */

         print_twice = 1;

         if (!is_range)

          {

            if (d)

             {

               /*

                  If the special value "99" for a day is given,

                    set the day to the last day of the month.

               */

               if (d == 99)

                {

                  if (m)

                   {

                     if (m == 2)

                       d = days_of_february ((y) ? y : year);

                     else

                       d = dvec[m-1];

                   }

                  else

                   {

                     if (month == 2)

                       d = days_of_february ((y) ? y : year);

                     else

                       d = dvec[month-1];

                   }

                }

               is_valid_date = valid_date (d, (m) ? m : month, (y) ? y : year);

             }

            if (!is_valid_date)

             {

               if (   (   !y

                       && (   (   (   m == 2

                                   || (   !m

                                       && (month == 2)))

                               && (d == 29))

                           || (   !m

                               && (d <= 31))))

                   || (   y

                       && !m

                       && (d <= 31)))

                 /*

                    If no month/year entry given, ignore that date.

                 */

                 ;

               else

                 /*

                    Invalid date field given.

                 */

                 my_error (123, filename, line_number, line_buffer, 0);

             }

            /*

               If a "n'th weekday of month" field is given, compute the according date.

            */

            if (n)

             {

               nth_weekday_of_month (&d, &m, &y, &n, &is_weekday_mode);

               if (!m)

                 /*

                    If the date is uncomputable (`m' is still 0), exit the loop.

                 */

                 break;

             }

            else

              if (!y)

               {

                 if (   hwd

                     && (   (fiscal_month > MONTH_MIN)

                         || (   (hc == RC_EASTER_CHAR)

                             && (   day < DAY_MIN

                                 || ed > DAY_LAST+is_leap_year+1))))

                   /*

                      Actually it's not possible to evaluate events, which

                        occur in every year and are set to a "n'th weekday"

                        displacement, and the mode of operation is generally

                        for fiscal years or for weeks, which have left the

                        bounds of the actual year and are related to the Easter

                        Sundays date, because Easter Sunday is on one date in

                        the current year and on another date in the other year!!

                        Grrr... seems I've to rework this for future releases

                                ...or will it be a feature???

                   */

                   y = -1;

                 else

                  {

                    /*

                       If @e... Easter holiday "date"-part is given, compute the according date.

                    */

                    if (hc == RC_EASTER_CHAR)

                     {

                       register int  epy=knuth_easter_formula (year-1);   /* Easter Sunday in previous year */

                       register int  eay=knuth_easter_formula (year);     /* Easter Sunday in current year */

                       register int  eny=knuth_easter_formula (year+1);   /* Easter Sunday in next year */





                       if (fiscal_month > MONTH_MIN)

                        {

                          /*

                             Precalculate the number of days in last month of fiscal year.

                          */

                          if (fiscal_month-1 == 2)

                            i = days_of_february (year+1);

                          else

                            i = dvec[fiscal_month-2];

                          /*

                             Manage fiscal year request.

                          */

                          if (year == EASTER_MIN-1)

                           {

                             j = day_of_year (i, fiscal_month-1, year+1);

                             if (hn+eny <= j)

                              {

                                if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))

                                  y = -1;

                              }

                             else

                               y = -1;

                           }

                          else

                           {

                             j = day_of_year (DAY_MIN, fiscal_month, year);

                             if (hn+eay >= j)

                              {

                                if (!precomp_date (hn, hwd, &d, &m, year, EAster))

                                  y = -1;

                                else

                                 {

                                   /*

                                      Check whether this single event occurs in the next year, too.

                                   */

                                   j = day_of_year (i, fiscal_month-1, year+1);

                                   if (   !is_3month_mode

                                       && !is_3month_mode2

                                       && (hn+eny <= j))

                                    {

                                      /*

                                         We need a 1x2 production of the line.

                                      */

                                      print_twice++;

                                      is_2easter = TRUE;

                                    }

                                 }

                              }

                             else

                              {

                                if (   is_3month_mode

                                    || is_3month_mode2)

                                 {

                                   if (fiscal_month >= MONTH_MAX-1)

                                    {

                                      j = dvec[MONTH_MIN-1];

                                      if (fiscal_month == MONTH_MAX)

                                        j += days_of_february (year+1) + is_leap_year;

                                      if (hn+eny <= j)

                                       {

                                         if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))

                                           y = -1;

                                       }

                                      else

                                        y = -1;

                                    }

                                   else

                                     y = -1;

                                 }

                                else

                                 {

                                   j = day_of_year (i, fiscal_month-1, year+1);

                                   if (hn+eny <= j)

                                    {

                                      if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))

                                        y = -1;

                                    }

                                   else

                                     y = -1;

                                 }

                              }

                           }

                        }

                       else

                         /*

                            Manage -c0w request resp.,

                              -cw in case date is in first days of January.

                         */

                         if (day < DAY_MIN)

                          {

                            j = DAY_LAST + (days_of_february (year-1) == 29);

                            if (   (hn+epy >= j+day)

                                && (hn+epy <= j))

                             {

                               if (!precomp_date (hn, hwd, &d, &m, year-1, EAster))

                                 y = -1;

                             }

                            else

                             {

                               if (hn+eay < ed)

                                {

                                  if (!precomp_date (hn, hwd, &d, &m, year, EAster))

                                    y = -1;

                                }

                               else

                                 y = -1;

                             }

                          }

                         else

                           /*

                              Manage -c99w (-c52w | -c53w) request resp.,

                                -ct or -cw in case date is in last days of December.

                           */

                           if (ed > DAY_LAST+is_leap_year+1)

                            {

                              j = DAY_LAST + is_leap_year;

                              if (   (hn+eay >= day)

                                  && (hn+eay <= j))

                               {

                                 if (!precomp_date (hn, hwd, &d, &m, year, EAster))

                                   y = -1;

                               }

                              else

                               {

                                 if (hn+eny < ed-j)

                                  {

                                    if (!precomp_date (hn, hwd, &d, &m, year+1, EAster))

                                      y = -1;

                                  }

                                 else

                                   y = -1;

                               }

                            }

                           else

                             /*

                                All other "ordinary" requests...

                             */

                             if (!precomp_date (hn, hwd, &d, &m, year, EAster))

                               y = -1;

                     }

                    else

                      /*

                         If @`dvar'... "date"-part is given, compute the according date.

                      */

                      if (islower(hc))

                       {

                         if (fiscal_month > MONTH_MIN)

                          {

                            register int  date_dvar=day_of_year (d, m, year);





                            /*

                               Precalculate number of days in the last month of fiscal year.

                            */

                            if (fiscal_month-1 == 2)

                              i = days_of_february (year+1);

                            else

                              i = dvec[fiscal_month-2];

                            /*

                               Manage fiscal year request.

                            */

                            j = day_of_year (DAY_MIN, fiscal_month, year);

                            /*

                               Buffer day and month.

                            */

                            d_buf = d;

                            m_buf = m;

                            if (hn+date_dvar >= j)

                             {

                               if (!precomp_date (hn, hwd, &d, &m, year, DVar))

                                 y = -1;

                               else

                                {

                                  /*

                                     Check whether this single event occurs in in next year, too.

                                  */

                                  j = day_of_year (i, fiscal_month-1, year+1);

                                  if (   !is_3month_mode

                                      && !is_3month_mode2

                                      && (hn+date_dvar <= j))

                                   {

                                     /*

                                        We need a 1x2 production of the line.

                                     */

                                     print_twice++;

                                     is_2dvar = TRUE;

                                   }

                                }

                             }

                            else

                             {

                               if (   is_3month_mode

                                   || is_3month_mode2)

                                {

                                  if (fiscal_month >= MONTH_MAX-1)

                                   {

                                     j = dvec[MONTH_MIN-1];

                                     if (fiscal_month == MONTH_MAX)

                                       j += days_of_february (year+1) + is_leap_year;

                                     if (hn+date_dvar <= j)

                                      {

                                        if (!precomp_date (hn, hwd, &d, &m, year+1, DVar))

                                          y = -1;

                                      }

                                     else

                                       y = -1;

                                   }

                                  else

                                    y = -1;

                                }

                               else

                                {

                                  j = day_of_year (i, fiscal_month-1, year+1);

                                  if (hn+date_dvar <= j)

                                   {

                                     if (!precomp_date (hn, hwd, &d, &m, year+1, DVar))

                                       y = -1;

                                   }

                                  else

                                    y = -1;

                                }

                             }

                          }

                         else

                           /*

                              All other "ordinary" requests...

                           */

                           if (!precomp_date (hn, hwd, &d, &m, year, DVar))

                             y = -1;

                       }

                      else

                        /*

                           If 0*d|w<n>[ww[w]] "date"-part is given, compute the according date.

                        */

                        if (   hc == 'D'

                            || hc == 'W')

                         {

                           y = year;

                           if (precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,

                                               (hc == 'D') ? DAy : WEek))

                            {

                              register int  date_dvar=day_of_year (d, m, y);





                              if (fiscal_month > MONTH_MIN)

                               {

                                 /*

                                    Precalculate the number of days of the last month of fiscal year.

                                 */

                                 if (fiscal_month-1 == 2)

                                   i = days_of_february (year+1);

                                 else

                                   i = dvec[fiscal_month-2];

                                 /*

                                    Manage fiscal year request.

                                 */

                                 j = day_of_year (DAY_MIN, fiscal_month, year);

                                 if (date_dvar >= j)

                                  {

                                    /*

                                       Check whether this single event occurs in the next year, too

                                    */

                                    j = day_of_year (i, fiscal_month-1, year+1);

                                    if (   !is_3month_mode

                                        && !is_3month_mode2

                                        && (date_dvar <= j))

                                     {

                                       /*

                                          Buffer day and month.

                                       */

                                       d_buf = d;

                                       m_buf = m;

                                       /*

                                          We need a 1x2 production of the line.

                                       */

                                       print_twice++;

                                       is_2dvar = TRUE;

                                     }

                                  }

                                 else

                                  {

                                    if (   is_3month_mode

                                        || is_3month_mode2)

                                     {

                                       if (fiscal_month >= MONTH_MAX-1)

                                        {

                                          j = dvec[MONTH_MIN-1];

                                          if (fiscal_month == MONTH_MAX)

                                            j += days_of_february (year+1) + is_leap_year;

                                          if (date_dvar <= j)

                                           {

                                             y++;

                                             (void)precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,

                                                                   (hc == 'D') ? DAy : WEek);

                                           }

                                          else

                                            y = -1;

                                        }

                                       else

                                         y = -1;

                                     }

                                    else

                                     {

                                       j = day_of_year (i, fiscal_month-1, year+1);

                                       if (date_dvar <= j)

                                        {

                                          y++;

                                          (void)precomp_nth_wd (hn, hwd, &hn, &d, &m, &y,

                                                                (hc == 'D') ? DAy : WEek);

                                        }

                                       else

                                         y = -1;

                                     }

                                  }

                               }

                            }

                         }

                  }

               }

          }

         /*

            Check whether this current line must be displayed.

         */

         if (y >= 0)

          {

            if (   !is_range

                && (repeat > 1))

              is_range = TRUE;

            if (date_matches_period (&print_twice, day, ed, wd))

              /*

                 Now insert this current line into `rc_elems_table[]'

                   (lines with no "text"-part are valid and are displayed).

              */

              insert_line_into_table (line_buffer, filename, line_number,

                                      rc_elems, len_date, print_twice);

          }

       }

      /*

         We have to restore some elements of the date and

           to precompute the next date if a range of days is given!

      */

      if (   lineptrs->day_range

          || repeat)

       {

         if (is_range)

          {

            if (m)

             {

               if (y <= 0)

                 y = year;

               if (appears)

                {

                  /*

                     Advance to the next date in period if an "appears" coding is given.

                  */

                  i = day_of_year (d, m, y);

                  (void)doy2date (i+appears+1, (days_of_february (y)==29), &d, &m);

                  productions -= appears;

                }

               else

                 next_date (&d, &m, &y);

               /*

                  If we evaluate a list of days and found "repeat" or "appears" fields

                    in it and made all necessary productions, we must manage this

                    explicitly by setting `is_range' to FALSE and `productions'

                    to any value greater 1, otherwise the next element of the

                    list would not be managed!

               */

               if (   lineptrs->day_list

                   && (productions <= 1)

                   && (lptrs->day_part != (char *)NULL))

                {

                  productions = 2;

                  is_range = FALSE;

                }

             }

            else

              /*

                 Such a date is uncomputable.

              */

              if (lineptrs->day_list)

               {

                 /*

                    The list of days still contains elements.

                 */

                 if (lptrs->day_part != (char *)NULL)

                  {

                    productions = 2;

                    is_range = FALSE;

                  }

                 else

                   /*

                      We are at the end of a list of days.

                   */

                   break;

               }

          }

         else

          {

            if (appears)

             {

               /*

                  Advance to the next date in period if an "appears" coding is given.

               */

               productions -= appears;

               if (productions > 0)

                 for (i=0 ; i <= appears ; i++)

                   if (++buf_d > DAY_MAX)

                     buf_d = DAY_MIN;

             }

            else

              if (++buf_d > DAY_MAX)

                buf_d = DAY_MIN;

            d = buf_d;

            m = buf_m;

            y = buf_y;

          }

       }

      else

        if (   lineptrs->day_list

            && (lptrs->day_part == (char *)NULL))

          /*

             We have already managed the last element of a list of days.

          */

          break;

    } while (--productions > 0);   /* I don't like the GNU-coding scheme for do-whiles */

   month = tmp_month;

   if (lineptrs->repeat_part != (char *)NULL)

     free(lineptrs->repeat_part);

   if (lineptrs->appears_part != (char *)NULL)

     free(lineptrs->appears_part);

}







   LOCAL Bool

date_matches_period (print_twice, day, ed, wd)

         int *print_twice;

         int  day;

         int  ed;

   const int  wd;

/*

   Checks if a given date (module global variables `d' for the day, `m' for

     the month and `y' for the year) matches a given period, which starts at

     absolute day of year `day' and ends at absolute day of year `ed' (the

     actual weekday is given in `wd').  If the given date matches the

     specified period, return TRUE, otherwise FALSE.

*/

{

   register int   i;

   register int   j;

   auto     int   dd;

   auto     int   mm;

   auto     int   yy;

   auto     Bool  print_line=FALSE;

   auto     Bool  is_valid_date=TRUE;





   if (   is_date_given

       || (   (year != act_year)

           && (day > 0))

       || (   (   month

               && (month != act_month))

           && (year == act_year)))

    {

      /*

         NOT in simple month-/year mode (an explicit date is given in command line):

           Manage -c[...] arguments.

      */

      if (   d

          && !is_weekday_mode)

       {

         incr_year = (   (fiscal_month > MONTH_MIN)

                      && (m < fiscal_month)

                      && (   !y

                          || y == year+1));

         if (   is_date_given

             && month

             && !changed_month

             && !m)

          {

            m = month;

            is_valid_date = valid_date (d, m, (y) ? y : year);

          }

         if (   is_valid_date

             && (   !y

                 || y-incr_year == year)

             && m

             && d)

          {

            if (   month

                && !changed_month)

             {

               if (m == month)

                {

                  if (   !is_leap_year

                      && (m == 2)

                      && (d == 29))

                    ;   /* If the year is no leap year, ignore that date */

                  else

                    print_line = TRUE;

                }

             }

            else

             {

               if (fiscal_month > MONTH_MIN)

                {

                  /*

                     Respect fiscal years!

                  */

                  if (   (   incr_year

                          && (year < YEAR_MAX))

                      || (   (m >= fiscal_month)

                          && (   !y

                              || y == year)))

                   {

                     if (   (days_of_february (year+incr_year) == 28)

                         && (m == 2)

                         && (d == 29))

                       ;   /* If the year is no leap year, ignore that date */

                     else

                       print_line = TRUE;

                   }

                }

               else

                 /*

                    Respect non fiscal years!

                 */

                 if (   !is_leap_year

                     && (m == 2)

                     && (d == 29))

                   ;   /* If the year is no leap year, ignore that date */

                 else

                   print_line = TRUE;

             }

          }

       }

    }

   else

    {

      /*

         Simple month-/year mode (NO explicit date is given in command line):

           Manage [-c[...]]w|m|y[+|-] arguments.

      */

      if (   (   rc_period_flag

              || rc_week_flag

              || rc_month_flag

              || rc_year_flag)

          && !is_date_given

          && (   !y

              || y == year

              || (   rc_week_flag

                  && (   (   (year+1 <= YEAR_MAX)

                          && (ed > DAY_LAST+is_leap_year+1))

                      || (   (year-1 >= YEAR_MIN)

                          && (day < DAY_MIN))))))

       {

         register int  td;





         if (   m

             && d)

          {

            if (   rc_week_flag

                && !y

                && (m != month))

             {

               if (   (ed > DAY_LAST+is_leap_year+1)

                   && !adate_set

                   && (   rc_forwards_flag

                       || (   !rc_forwards_flag

                           && !rc_backwards_flag)))

                 y = year + 1;

               else

                 if (   (day < DAY_MIN)

                     && !adate_set

                     && (   rc_backwards_flag

                         || (   !rc_forwards_flag

                             && !rc_backwards_flag)))

                   y = year - 1;

             }

            if (   y < YEAR_MIN

                || y > YEAR_MAX)

             {

               if (adate_set)

                {

                  if (m == month)

                   {

                     if (day < DAY_MIN)

                       y = year - 1;

                   }

                  else

                   {

                     if (ed > DAY_LAST+is_leap_year+1)

                       y = year + 1;

                   }

                  if (   y < YEAR_MIN

                      || y > YEAR_MAX)

                    y = year;

                }

               else

                 y = year;

             }

          }

         if (   (   rc_week_flag

                 && is_weekday_mode)

             || (   !is_weekday_mode

                 && (   y

                     || m

                     || d)))

          {

            /*

               Respect short day name entry `yyyymmww[w]' ... (ww[w]==short dayname).

            */

            if (   rc_week_flag

                && is_weekday_mode)

             {

               static struct {

                               char day[DAY_MAX];

                               char dst[DAY_MAX];

                             } wday_list;

               static Bool     fill_wday_list=FALSE;





               j = 0;

               if (!fill_wday_list)

                {

                  if (   rc_forwards_flag

                      || (   !rc_forwards_flag

                          && !rc_backwards_flag))

                   {

                     i = wd;

                     LOOP

                      {

                        wday_list.day[i-1] = (char)i;

                        wday_list.dst[i-1] = (char)j++;

                        i++;

                        if (i > DAY_MAX)

                          i = DAY_MIN;

                        if (i == start_day)

                          break;

                      }

                   }

                  j = 0;

                  if (   rc_backwards_flag

                      || (   !rc_forwards_flag

                          && !rc_backwards_flag))

                   {

                     i = wd;

                     LOOP

                      {

                        if (i < DAY_MIN)

                          i = DAY_MAX;

                        wday_list.day[i-1] = (char)i;

                        wday_list.dst[i-1] = (char)++j;

                        if (i == start_day)

                          break;

                        i--;

                      }

                   }

                  fill_wday_list = TRUE;

                }

               if (wday_list.day[d-1])

                {

                  yy = year;

                  if (rc_week_year_flag)

                   {

                     j = day;

                     if (day < 1)

                      {

                        yy = year - 1;

                        j += (DAY_LAST + (days_of_february (yy) == 29));

                      }

                     (void)doy2date (j, (days_of_february (yy)==29), &dd, &mm);

                   }

                  else

                   {

                     dd = act_day;

                     mm = month;

                   }

                  if (rc_forwards_flag)

                    for (i=0 ; i < wday_list.dst[d-1] ; i++)

                      next_date (&dd, &mm, &yy);

                  else

                    if (rc_backwards_flag)

                      for (i=1 ; i < wday_list.dst[d-1] ; i++)

                        prev_date (&dd, &mm, &yy);

                    else

                     {

                       i = SYEAR(d, start_day);

                       j = SYEAR(wd, start_day);

                       if (i-j <= 0)

                         for (i=1 ; i < wday_list.dst[d-1] ; i++)

                           prev_date (&dd, &mm, &yy);

                       else

                         for (i=0 ; i < wday_list.dst[d-1] ; i++)

                           next_date (&dd, &mm, &yy);

                     }

                  if (   (   !m

                          || m == mm)

                      && (   !y

                          || y == yy))

                   {

                     d = dd;

                     m = mm;

                     y = yy;

                   }

                  else

                    y = -1;

                }

               else

                 y = -1;

             }

            if (   rc_week_flag

                && (y >= 0)

                && (   day < DAY_MIN

                    || ed > DAY_LAST+is_leap_year+1))

             {

               if (   (   rc_backwards_flag

                       || (   !rc_forwards_flag

                           && !rc_backwards_flag))

                   && (y == year-1)

                   && m

                   && d)

                {

                  ed = DAY_LAST + (days_of_february (y) == 29);

                  day = ed + day;

                  td = day_of_year (d, m, y);

                  if (   (td <= ed)

                      && (td >= day))

                   {

                     decr_year = 1;

                     print_line = TRUE;

                   }

                }

               else

                 if (   (   rc_forwards_flag

                         || (   !rc_forwards_flag

                             && !rc_backwards_flag))

                     && (y == year+1)

                     && m

                     && d)

                  {

                    td = day_of_year (d, m, y) + DAY_LAST + is_leap_year;

                    if (   (td < ed)

                        && (td >= day))

                     {

                       incr_year = 1;

                       print_line = TRUE;

                     }

                  }

                 else

                  {

                    if (   (   y == year

                            || (   (y == year-1)

                                && !rc_forwards_flag)

                            || (   (y == year+1)

                                && !rc_backwards_flag))

                        && m

                        && d)

                     {

                       td = day_of_year (d, m, y);

                       if (   (td < ed)

                           && (td >= day))

                         print_line = TRUE;

                     }

                    else

                      if (d)

                       {

                         td = 0;

                         m = month;

                         if (day < DAY_MIN)

                          {

                            if (   !y

                                || y == year

                                || y == year-1)

                             {

                               if (adate_set)

                                 i = dvec[MONTH_MAX-1] + day - 1;

                               else

                                 i = dvec[MONTH_MAX-1] + act_day - (SYEAR(wd, start_day));

                               if (d > i)

                                {

                                  m = MONTH_MAX;

                                  if (!y)

                                    y = year - 1;

                                  if (y == year)

                                    td = day_of_year (d, m, year);

                                  else

                                   {

                                     ed = DAY_LAST + (days_of_february (y) == 29);

                                     day = ed + day;

                                     td = day_of_year (d, m, y);

                                     decr_year = 1;

                                   }

                                }

                               else

                                 if (   !y

                                     || y == year)

                                  {

                                    if (adate_set)

                                     {

                                       m = MONTH_MIN;

                                       td = day_of_year (d, m, year) + 1;

                                     }

                                    else

                                      td = day_of_year (d, m, year) + 1;

                                  }

                                 else

                                   td = ed + 1;

                               if (   (td <= ed)

                                   && (td >= day))

                                 print_line = TRUE;

                             }

                          }

                         else

                           if (   !y

                               || y == year

                               || y == year+1)

                            {

                              i = act_day - (SYEAR(wd, start_day));

                              if (d < i)

                               {

                                 m = MONTH_MIN;

                                 if (!y)

                                   y = year + 1;

                                 if (y == year+1)

                                  {

                                    td = day_of_year (d, m, y) + DAY_LAST + is_leap_year;

                                    incr_year = 1;

                                  }

                               }

                              else

                                if (   !y

                                    || y == year)

                                  td = day_of_year (d, m, year);

                              if (   (td < ed)

                                  && (td >= day))

                                print_line = TRUE;

                            }

                       }

                  }

             }

            else

              if (   y >= 0

                  || y == year)

               {

                 if (   (   (   rc_month_flag

                             || rc_week_flag

                             || rc_period_flag)

                         && m

                         && !d)

                     || (   (   rc_month_flag

                             || rc_week_flag)

                         && !m

                         && !d)

                     || (   (   rc_year_flag

                             || rc_period_list)

                         && (   !m

                             || !d)))

                   ;   /* Void, ignore such entries! */

                 else

                  {

                    register int  mmm=m;





                    if (!y)

                      y = year;

                    if (!m)

                     {

                       mmm=m = month;

                       (void)doy2date (day, is_leap_year, &dd, &mm);

                       if (   (dd > d)

                           && (mm == m))

                         m++;

                       else

                         if (   (dd < d)

                             && (mm < m))

                           m--;

                     }

                    /*

                       If a valid date is given, respect it.

                    */

                    if (valid_date (d, m, y))

                     {

                       td = day_of_year (d, m, y);

                       if (   (td >= day)

                           && (td < ed))

                         print_line = TRUE;

                       else

                         m = mmm;

                     }

                    else

                      m = mmm;

                  }

               }

          }

       }

      else

        if (   !rc_period_flag

            && !rc_week_flag

            && !rc_month_flag

            && !rc_year_flag)

         {

           /*

              Simple month-/year month mode (NO explicit date is given in command line):

                Manage -c[...] or -c[...]t arguments.

           */

           dd = act_day;

           mm = month;

           yy = year;

           if (rc_tomorrow_flag)

             next_date (&dd, &mm, &yy);

           if (   (   !y

                   || y == year

                   || (   rc_tomorrow_flag

                       && (ed > DAY_LAST+is_leap_year+1)

                       && (y == year+1)

                       && (   !m

                           || m == mm)))

               && (   !m

                   || m == month

                   || (   rc_tomorrow_flag

                       && (m == mm)

                       && (   !y

                           || (   (ed > DAY_LAST+is_leap_year+1)

                               && (y == year+1))

                           || (   (ed <= DAY_LAST+is_leap_year+1)

                               && (y == year))))))

            {

              if (is_weekday_mode)

               {

                 /*

                    Respect short day name entry `yyyymmww[w]' ... (ww[w]==short dayname).

                 */

                 i = weekday_of_date (act_day, month, year);

                 j = 0;

                 if (rc_tomorrow_flag)

                   j = (d == weekday_of_date (dd, mm, yy));

                 if (   (   (d == i)

                         && (ed <= DAY_LAST+is_leap_year+1)

                         && (   !m

                             || m == month))

                     || (   (d == i)

                         && (   (ed > DAY_LAST+is_leap_year+1)

                             && (   (   !y

                                     && (   !m

                                         || m == month))

                                 || y == year)))

                     || (   j

                         && (   !m

                             || m == month+1

                             || m == mm)

                         && (   !y

                             || (   (ed > DAY_LAST+is_leap_year+1)

                                 && (y == year+1))

                             || (   (ed <= DAY_LAST+is_leap_year+1)

                                 && (y == year)))))

                  {

                    if (j)

                     {

                       m = mm;

                       d = dd;

                       if (   rc_tomorrow_flag

                           && (yy != year))

                         incr_year = 1;

                     }

                    else

                     {

                       m = month;

                       d = act_day;

                     }

                    if (   rc_tomorrow_flag

                        && !rc_have_today_in_list

                        && (d != dd))

                      ;   /* Void, ignore such entries! */

                    else

                      print_line = TRUE;

                  }

               }

              else

                if (   !d

                    || (   (d == act_day)

                        && (   !m

                            || m == month)

                        && (   !y

                            || y == year))

                    || (   (d == dd)

                        && (   mm == month

                            || (   rc_tomorrow_flag

                                && (   (   !m

                                        && (ed <= DAY_LAST+is_leap_year+1)

                                        && (   !y

                                            || y == year))

                                    || m == month+1

                                    || m == mm)))))

                 {

                   if (rc_tomorrow_flag)

                    {

                      if (   !d

                          && (   !m

                              || (   mm == month

                                  || m == month+1

                                  || m == mm)))

                       {

                         if (   (yy > year)

                             && (   d

                                 || m

                                 || y))

                          {

                            if (   !y

                                || y == yy)

                             {

                               m = mm;

                               d = dd;

                               incr_year = 1;

                             }

                          }

                         else

                           if (   m

                               || y != year

                               || ed <= DAY_LAST+is_leap_year+1)

                            {

                              if (   !d

                                  && m

                                  && (mm != month)

                                  && (   !y

                                      || y == year))

                               {

                                 m = mm;

                                 d = dd;

                               }

                              else

                               {

                                 if (rc_have_today_in_list)

                                   /*

                                      We need a 1x2 production of the line.

                                   */

                                   (*print_twice)++;

                                 else

                                  {

                                    m = mm;

                                    d = dd;

                                    if (yy != year)

                                      incr_year = 1;

                                  }

                               }

                            }

                       }

                      else

                       {

                         if (   (d == dd)

                             && (   !m

                                 || m == mm))

                          {

                            m = mm;

                            if (ed > DAY_LAST+is_leap_year+1)

                              incr_year = 1;

                          }

                       }

                    }

                   if (!m)

                     m = month;

                   if (!d)

                     d = act_day;

                   if (   rc_tomorrow_flag

                       && !rc_have_today_in_list

                       && (d != dd))

                     ;   /* Void, ignore such entries! */

                   else

                     print_line = TRUE;

                 }

            }

         }

    }

   /*

      Avoid an incorrect assignment in case fixed date mentioned occurred

        during the missing period in month of Gregorian Reformation.

   */

   if (   print_line

       && (year+incr_year-decr_year == greg->year)

       && (m == greg->month)

       && (   (d >= greg->first_day)

           && (d <= greg->last_day)))

     print_line = FALSE;

   /*

      If 3-month mode is wanted, insert only those fixed date warnings

        which occur in that period.

   */

   if (   print_line

       && (   is_3month_mode

           || is_3month_mode2))

    {

      register int  m2=fiscal_month+1;

      register int  m3=fiscal_month+2;





      if (fiscal_month >= MONTH_MAX-1)

       {

         m3 = MONTH_MIN;

         if (fiscal_month == MONTH_MAX)

          {

            m2 = MONTH_MIN;

            m3++;

          }

       }

      if (   (m != fiscal_month)

          && (m != m2)

          && (m != m3))

        print_line = FALSE;

    }



   return print_line;

}







   LOCAL void

insert_line_into_table (line_buffer, filename, line_number, rc_elems, len_date, print_twice)

         char *line_buffer;

   const char *filename;

   const long  line_number;

         int  *rc_elems;

         int   len_date;

         int   print_twice;

/*

   Inserts a line into `rc_elems_table[]',

     but before this the line is checked and evaluated first

     for $... text variables and then for %... macro texts.

*/

{

   auto     Slint  num;

   register int    i;

   register int    j;

   register int    k;

   register int    len_fn=len_year_max+5;   /* Position of the `(' of the "(FILENAME)" text */

   register int    tmp_year=year;

   auto     int    len;

   auto     int    dd;

   auto     int    mm;

   auto     int    yy;

   auto     int    nn;

   auto     int    hhn;

   auto     int    hhwd;

   auto     char  *ptr_char=line_buffer+len_date;

   auto     char   hhc;

   auto     Bool   hls1_set;

   auto     Bool   hls2_set;

   auto     Bool   is_weekday_mode;

   auto     Bool   ok;

   auto     Bool   print_line=TRUE;

   auto     Bool   is_obsolete_whitespace=FALSE;





   if (rc_enable_fn_flag)

     len_fn += (int)strlen(filename) + 3;   /* +3 due to the "(THE_REAL_FILENAME_ITSELF) " text */

   /*

      Skip the delimiting whitespace characters between the "date"-part and the "text"-part.

   */

   while (isspace(*ptr_char))

     ptr_char++;

   if (*ptr_char)

    {

      /*

         If the "text"-part starts with a QUOTEd whitespace character, exchange

           the QUOTE character by a PSEUDO_QUOTE character ('\001') to keep the

           internal sorting order intact.

      */

      if (   (*ptr_char == QUOTE_CHAR)

          && isspace(*(ptr_char + 1)))

        *ptr_char = PSEUDO_QUOTE;

      if ((Uint)len_the_text < maxlen_max)

       {

         len_the_text = (int)maxlen_max;

         the_text = (char *)my_realloc ((VOID_PTR)the_text, len_the_text,

                                        124, __FILE__, ((long)__LINE__)-1,

                                        "the_text", len_the_text);

       }

      strcpy(the_text, ptr_char);

    }

   else

     /*

        No "text"-part given.

     */

     *the_text = '\0';

   do

    {

      /*

         Check line for %... macros and quoted $... text variables.

      */

      j=k = 0;

      ok=hls1_set=hls2_set = FALSE;

      while (!ok)

       {

         while (*(the_text + j))

          {

            if ((Uint)k >= maxlen_max-(Uint)len_fn)

              resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

            if (   *(the_text + j) == RC_MACRO_CHAR

                || *(the_text + j) == RC_TVAR_CHAR)

             {

               if (j)

                {

                  /*

                     Check if the %... macro or the $... text variable is quoted.

                  */

                  if (*(the_text + (j - 1)) == QUOTE_CHAR)

                    k--;

                  else

                    if (*(the_text + j) == RC_MACRO_CHAR)

                      break;

                }

               else

                 if (*(the_text + j) == RC_MACRO_CHAR)

                   break;

             }

            if (   is_obsolete_whitespace

                && isspace(*(the_text + j)))

             {

               is_obsolete_whitespace = FALSE;

               j++;

             }

            else

              s1[k++] = *(the_text + j++);

          }

         if ((Uint)k >= maxlen_max-(Uint)len_fn)

           resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

         if (*(the_text + j))

          {

            auto Bool  is_b;

            auto Bool  is_s;

            auto Bool  is_e;

            auto Bool  is_o;

            auto Bool  is_k;

            auto Bool  is_n;

            auto Bool  is_d;

            auto Bool  is_w;

            auto Bool  is_m;

            auto Bool  is_y;

            auto Bool  is_t;

            auto Bool  is_j;

            auto Bool  is_1;

            auto Bool  is_2;

            auto Bool  is_3;

            auto Bool  is_4;





            /*

               A '%' character (macro prefix) found!

            */

            j++;

            is_b = (Bool)(tolower(*(the_text + j)) == RC_BYEAR_CHAR);

            is_s = (Bool)(tolower(*(the_text + j)) == RC_SDATE_CHAR);

            is_e = (Bool)(tolower(*(the_text + j)) == RC_EDATE_CHAR);

            is_o = (Bool)(tolower(*(the_text + j)) == RC_WNAME_CHAR);

            is_k = (Bool)(tolower(*(the_text + j)) == RC_WNUMBER_CHAR);

            is_n = (Bool)(tolower(*(the_text + j)) == RC_DATE_CHAR);

            is_d = (Bool)(tolower(*(the_text + j)) == RC_DAY_CHAR);

            is_w = (Bool)(tolower(*(the_text + j)) == RC_WEEK_CHAR);

            is_m = (Bool)(tolower(*(the_text + j)) == RC_MONTH_CHAR);

            is_y = (Bool)(tolower(*(the_text + j)) == RC_YEAR_CHAR);

            is_t = (Bool)(tolower(*(the_text + j)) == RC_TIME_CHAR);

            is_j = (Bool)(tolower(*(the_text + j)) == RC_JDAYS_CHAR);

            is_1 = (Bool)(tolower(*(the_text + j)) == RC_HLS1S_CHAR);

            is_2 = (Bool)(tolower(*(the_text + j)) == RC_HLS1E_CHAR);

            is_3 = (Bool)(tolower(*(the_text + j)) == RC_HLS2S_CHAR);

            is_4 = (Bool)(tolower(*(the_text + j)) == RC_HLS2E_CHAR);

            /*

               Check for

                 %n[[+|-]<n>] or

                 %o[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %o`yyyy'@..., %o`yyyy'*... or

                 %k[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %o`yyyy'@..., %o`yyyy'*... or

                 %s[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@..., %s`yyyy'*... or

                 %e[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %e`yyyy'@..., %e`yyyy'*... or

                 %b[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %b`yyyy'@..., %b`yyyy'*... or

                 %y[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %y`yyyy'@..., %y`yyyy'*... macros

            */

            if (   is_b

                || is_s

                || is_e

                || is_o

                || is_k

                || is_n

                || (   is_y

                    && *(the_text + j + 1)

                    && !isspace(*(the_text + j + 1))))

             {

               j++;

               if (!is_n)

                {

                  (void)rc_get_date (the_text+j, lptrs2, FALSE, &is_weekday_mode, &dd, &mm, &yy, &nn,

                                     &len, &hhc, &hhn, &hhwd, filename, line_number, the_text+j-2, TRUE);

                  j += len;

                  if (!yy)

                   {

                     yy = year;

                     if (   y

                         && (fiscal_month > MONTH_MIN))

                       yy = y;

                   }

                  /*

                     Respect possible fiscal year.

                  */

                  if (yy != -1)

                   {

                     yy -= incr_year;

                     yy += decr_year;

                   }

                  /*

                     If @... "date"-part is given, compute the according date.

                  */

                  if (hhc == RC_EASTER_CHAR)

                   {

                     if (fiscal_month > MONTH_MIN)

                      {

                        if (!precomp_date (hhn, hhwd, &dd, &mm, yy+incr_year, EAster))

                          yy = -1;

                      }

                     else

                       if (!precomp_date (hhn, hhwd, &dd, &mm, yy, EAster))

                         yy = -1;

                   }

                  else

                    if (islower(hhc))

                     {

                       if (rc_dvar[IDX(hhc)].l.month)

                        {

                          mm = (int)rc_dvar[IDX(hhc)].l.month;

                          dd = (int)rc_dvar[IDX(hhc)].l.day;

                        }

                       else

                         if (rc_dvar[IDX(hhc)].g.month)

                          {

                            mm = (int)rc_dvar[IDX(hhc)].g.month;

                            dd = (int)rc_dvar[IDX(hhc)].g.day;

                          }

                       if (fiscal_month > MONTH_MIN)

                        {

                          if (!precomp_date (hhn, hhwd, &dd, &mm, yy+incr_year, DVar))

                            yy = -1;

                        }

                       else

                         if (!precomp_date (hhn, hhwd, &dd, &mm, yy, DVar))

                           yy = -1;

                     }

                    else

                      if (   hhc == 'D'

                          || hhc == 'W')

                       {

                         if (fiscal_month > MONTH_MIN)

                          {

                            auto int  fiscal_year=yy+incr_year;





                            if (!precomp_nth_wd (hhn, hhwd, &hhn, &dd, &mm, &fiscal_year,

                                                 (hhc == 'D') ? DAy : WEek))

                              yy = fiscal_year;

                          }

                         else

                           (void)precomp_nth_wd (hhn, hhwd, &hhn, &dd, &mm, &yy,

                                                 (hhc == 'D') ? DAy : WEek);

                       }

                  if (len > len_year_max)

                    len -= len_year_max;

                  else

                    len = 0;

                  /*

                     %s[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...

                       starting year macro found.

                  */

                  if (is_s)

                   {

                     /*

                        Assume current/first month of year.

                     */

                     if (!mm)

                      {

                        if (len >= 1)

                         {

                           mm = m;

                           if (len == 2)

                             len = 0;

                           else

                             len--;

                         }

                        else

                          mm = MONTH_MIN;

                      }

                     else

                      {

                        if (len == 2)

                          len = 0;

                        else

                          len--;

                      }

                     /*

                        Assume current/first day of month.

                     */

                     if (!dd)

                      {

                        if (len >= 1)

                          dd = d;

                        else

                          dd = DAY_MIN;

                      }

                   }

                  else

                    /*

                       %e[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...

                         ending (final) year macro found.

                    */

                    if (is_e)

                     {

                       /*

                          Assume current/last month of year.

                       */

                       if (!mm)

                        {

                          if (len >= 1)

                           {

                             mm = m;

                             if (len == 2)

                               len = 0;

                             else

                               len--;

                           }

                          else

                            mm = MONTH_MAX;

                        }

                       else

                        {

                          if (len == 2)

                            len = 0;

                          else

                            len--;

                        }

                       /*

                          Assume current/last day of month.

                       */

                       if (!dd)

                        {

                          if (len >= 1)

                            dd = d;

                          else

                           {

                             if (mm == 2)

                              {

                                if (fiscal_month > MONTH_MIN)

                                  dd = days_of_february (yy+incr_year);

                                else

                                  dd = days_of_february (yy);

                              }

                             else

                               dd = dvec[mm-1];

                           }

                        }

                     }

                    else

                     /*

                        %b[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...

                          birth year macro or

                        %o[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %o`yyyy'@... or %o`yyyy'*...

                          weeday name text macro or

                        %y[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...

                          year macro found.

                     */

                     {

                       /*

                          Assume current month/day.

                       */

                       if (!mm)

                         mm = m;

                       if (!dd)

                         dd = d;

                     }

                  /*

                     If special value "99" for day `dd' is given,

                       set the day to last day of month.

                  */

                  if (dd == 99)

                   {

                     /*

                        Assume the last day of month.

                     */

                     if (mm == 2)

                      {

                        if (   is_e

                            && (fiscal_month > MONTH_MIN))

                          dd = days_of_february (yy+incr_year);

                        else

                          dd = days_of_february (yy);

                      }

                     else

                       dd = dvec[mm-1];

                   }

                  /*

                     If "n'th weekday of month" entry set, compute the according date.

                  */

                  if (nn)

                    nth_weekday_of_month (&dd, &mm, &yy, &nn, &is_weekday_mode);

                  /*

                     Compute the day difference of the two dates.

                  */

                  if (yy >= 0)

                   {

                     if (   !nn

                         && (   fiscal_month > MONTH_MIN

                             || (   incr_year

                                 && (   rc_tomorrow_flag

                                     || rc_week_flag))))

                       yy += incr_year;

                     if (   is_o

                         || is_k)

                       yy += incr_year;

                     else

                       num = d_between (dd, mm, yy, d, m, (y) ? y : year+incr_year);

                     /*

                        Starting date of event greater current date resp.,

                          ending (final) date of event smaller current date:

                          Avoid displaying the fixed date text.

                     */

                     if (is_s)

                      {

                        if (num < 0L)

                         {

                           ok = TRUE;

                           print_line = FALSE;

                         }

                      }

                     else

                       if (is_e)

                        {

                          if (num > 0L)

                           {

                             ok = TRUE;

                             print_line = FALSE;

                           }

                        }

                       else

                        /*

                           Manage

                             %b[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...

                               birth year macros and

                             %y[`yyyy'[`mm'[`dd'|`ww[w]'[<n>]]]], %s`yyyy'@... or %s`yyyy'*...

                               year macros.

                        */

                        {

                          if (is_b)

                           {

                             yy = ((y) ? y : year+incr_year) - yy;

                             if (   m < mm

                                 || (   (m == mm)

                                     && (d < dd)))

                               yy--;

                           }

                          else

                            if (is_y)

                             {

                               /*

                                  `is_y' is active.

                               */

                               yy = yy - ((y) ? y : year+incr_year);

                               if (   m < mm

                                   || (   (m == mm)

                                       && (d < dd)))

                                {

                                  if (yy < 1)

                                    yy++;

                                  else

                                    if (yy > 1)

                                      yy--;

                                }

                             }

                          if (   is_b

                              && (yy < 1))

                            ;   /* Void, don't manage resp., suppress such dates */

                          else

                           {

                             if (is_o)

                               /*

                                  Print the effective weekday name text.

                               */

                               sprintf(s2, "%s", day_name (weekday_of_date (dd, mm, yy)));

                             else

                               if (is_k)

                                {

                                  /*

                                     Print the week number.

                                  */

                                  i = week_number (dd, mm, yy);

                                  /*

                                     We convert the computed week number to a week number text

                                     (that looks nicer in output).

                                  */

                                  if (i < 0)

                                    /*

                                       Week starts in previous year and the first days

                                         of the actual year are not in its first week.

                                    */

                                    sprintf(s2, "%02d/0", -i);

                                  else

                                    if (!i)

                                      /*

                                         Week starts in previous year and the first days

                                           of the actual year are in its first week.

                                      */

                                      sprintf(s2, "%s", "53/1");

                                    else

                                      /*

                                         Week starts in actual year.

                                      */

                                      sprintf(s2, "%02d", i);

                                }

                               else

                                 /*

                                    Print the year difference value.

                                 */

                                 sprintf(s2, "%d", yy);

                             i = 0;

                             while (s2[i])

                              {

                                if ((Uint)k >= maxlen_max-(Uint)len_fn)

                                  resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                                s1[k++] = s2[i++];

                              }

                             if (   is_b

                                 && use_day_suffix)

                              {

                                sprintf(s2, "%s", day_suffix (yy));

                                i = 0;

                                while (s2[i])

                                 {

                                   if ((Uint)k >= maxlen_max-(Uint)len_fn)

                                     resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                                   s1[k++] = s2[i++];

                                 }

                              }

                           }

                        }

                     if (!*(the_text + j))

                       ok = TRUE;

                   }

                  is_obsolete_whitespace = TRUE;

                }

               else

                {

                  auto Slint  jdate;





                  /*

                     A %n[[+|-]<n>] macro found.

                  */

                  i = 0;

                  if (   *(the_text + j) == *ASC_LIT

                      || *(the_text + j) == *DES_LIT)

                    s2[i++] = *(the_text + j++);

                  while (isdigit(*(the_text + j)))

                   {

                     if ((Uint)i >= maxlen_max)

                       resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                     s2[i++] = *(the_text + j++);

                   }

                  s2[i] = '\0';

                  num = atol(s2);

                  y = year + incr_year - decr_year;

                  jdate = (Slint)date2num (d, m, y);

                  if (   (jdate+num <= (Slint)date2num (dvec[MONTH_MAX-1], MONTH_MAX, YEAR_MAX))

                      && (jdate+num >= 1L))

                   {

                     num2date (jdate+num, &dd, &mm, &yy);

                     sprintf(s2, "%02d-%s-%0*d", dd,

                             short_month_name (mm), len_year_max, yy);

                   }

                  else

                    *s2 = '\0';

                  i = 0;

                  while (s2[i])

                   {

                     if ((Uint)k >= maxlen_max-(Uint)len_fn)

                       resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                     s1[k++] = s2[i++];

                   }

                }

             }

            else

             {

               /*

                  A '%' character (macro prefix) found:

                    check for simple %t[12|24], %j[[-]<n>], %d, %w, %m, %y

                    %1, %2, %3 and %4 macros.

               */

               if (   is_t

                   || is_d

                   || is_w

                   || is_m

                   || is_y

                   || is_j

                   || is_1

                   || is_2

                   || is_3

                   || is_4)

                {

                  if (is_t)

                   {

                     register int   tmp_ah=act_hour;

                     static   char  time_suffix[3];

                     auto     Bool  is_12_hours_format=FALSE;





                     /*

                        Simple %t[12|24] macro found:

                          Replace it by the current system time hh:mm[am|pm].

                     */

                     j++;

                     if (isdigit(*(the_text + j)))

                      {

                        if (*(the_text + j) == '1')

                          is_12_hours_format = TRUE;

                        while (isdigit(*(the_text + j)))

                          j++;

                      }

                     j--;

                     if (is_12_hours_format)

                      {

                        /*

                           Copy a trailing "am" resp., "pm" suffix to text.

                        */

                        if (tmp_ah >= 12)

                         {

#  if USE_GER

                           strcpy(time_suffix, RC_PM_TXT);

#  else /* !USE_GER */

                           strcpy(time_suffix, _("pm"));

#  endif /* !USE_GER */

                           if (tmp_ah > 12)

                             tmp_ah -= 12;

                         }

                        else

#  if USE_GER

                          strcpy(time_suffix, RC_AM_TXT);

#  else /* !USE_GER */

                          strcpy(time_suffix, _("am"));

#  endif /* !USE_GER */

                      }

                     else

                       *time_suffix = '\0';

#  if USE_GER

                     sprintf(s2, "%02d%s%02d%s", tmp_ah, TIME_SEP, act_min, time_suffix);

#  else /* !USE_GER */

                     sprintf(s2, "%02d%s%02d%s", tmp_ah, _(":"), act_min, time_suffix);

#  endif /* !USE_GER */

                   }

                  else

                    if (   is_1

                        || is_2

                        || is_3

                        || is_4)

                     {

                       /*

                          One of the hightlighting macros found:

                            Replace it by the real hightlighting sequence.

                       */

                       *s2 = '\0';

                       if (highlight_flag)

                        {

                          if (   is_1

                              && !hls1_set)

                           {

                             sprintf(s2, "%s", ehls1s.seq);

                             hls1_set = TRUE;

                             hls2_set = FALSE;

                           }

                          else

                            if (   is_2

                                && hls1_set)

                             {

                               sprintf(s2, "%s", ehls1e.seq);

                               hls1_set = FALSE;

                             }

                            else

                              if (   is_3

                                  && !hls2_set)

                               {

                                 sprintf(s2, "%s", ehls2s.seq);

                                 hls2_set = TRUE;

                                 hls1_set = FALSE;

                               }

                              else

                                if (   is_4

                                    && hls2_set)

                                 {

                                   sprintf(s2, "%s", ehls2e.seq);

                                   hls2_set = FALSE;

                                 }

                        }

                     }

                    else

                     {

                       auto Slint  diff;





                       /*

                          Simple %j[[-]<n>], %d, %w, %m or %y macro found:

                            Replace it by the according computed number.

                       */

                       dd = act_day;

                       mm = act_month;

                       yy = act_year;

                       (void)get_actual_date ();

                       y = year + incr_year - decr_year;

                       /*

                          Now compute the differences:

                            date1 == actual (base)date (act_day, act_month, act_year)

                            date2 == reported date (d, m, y)

                       */

                       if (is_j)

                        {

                          /*

                             A %j[[-]<n>] macro found

                               (we always suppress the day fraction part of 0.5).

                          */

                          diff = d_between (1, 1, 1, d, m, y);

                          j++;

                          if (*(the_text + j) == *DES_LIT)

                            j++;

                          i = 0;

                          while (isdigit(*(the_text + j)))

                           {

                             if ((Uint)i >= maxlen_max)

                               resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                             s2[i++] = *(the_text + j++);

                           }

                          s2[i] = '\0';

                          j--;

                          num = atol(s2);

                          diff += (RC_MIN_BCE_TO_1_CE - num);

                        }

                       else

                         if (is_d)

                           diff = d_between (act_day, act_month, act_year, d, m, y);

                         else

                           if (is_w)

                             diff = w_between (act_day, act_month, act_year, d, m, y);

                           else

                             if (is_m)

                               diff = m_between (act_month, act_year, m, y);

                             else

                               /*

                                  A simple %y macro found.

                               */

                               diff = (Slint)y - act_year;

                       sprintf(s2, "%ld", diff);

                       act_day = dd;

                       act_month = mm;

                       act_year = yy;

                     }

                  i = 0;

                  while (s2[i])

                   {

                     if ((Uint)k >= maxlen_max-(Uint)len_fn)

                       resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                     s1[k++] = s2[i++];

                   }

                  j++;

                }

               else

                 s1[k++] = *(the_text + (j - 1));

             }

          }

         else

           ok = TRUE;

         if (ok)

          {

            if (   highlight_flag

                && (   hls1_set

                    || hls2_set))

             {

               /*

                  Hmm, seems the user forgot to give a macro text

                    for disabling an already enabled highlighting sequence,

                    let's do this for him/her/it/per/or or or...  hehehe!

               */

               if (hls1_set)

                {

                  if (ehls1e.len == 1)

                   {

                     if ((Uint)k >= maxlen_max-(Uint)len_fn-1)

                       resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                     s1[k++] = *ehls1e.seq;

                   }

                  else

                   {

                     while ((Uint)k >= maxlen_max-(Uint)len_fn-(ehls1e.len+1))

                       resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                     s1[k] = '\0';

                     strcat(s1, ehls1e.seq);

                     k += (ehls1e.len + 1);

                   }

                }

               else

                {

                  if (ehls2e.len == 1)

                   {

                     if ((Uint)k >= maxlen_max-(Uint)len_fn-1)

                       resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                     s1[k++] = *ehls2e.seq;

                   }

                  else

                   {

                     while ((Uint)k >= maxlen_max-(Uint)len_fn-(ehls2e.len+1))

                       resize_all_strings (maxlen_max<<1, __FILE__, (long)__LINE__);

                     s1[k] = '\0';

                     strcat(s1, ehls2e.seq);

                     k += (ehls2e.len + 1);

                   }

                }

             }

            if (print_line)

              s1[k] = '\0';

          }

       }

      if (print_line)

       {

         if (rc_enable_fn_flag)

          {

            if (*s1)

              sprintf(s6, "%0*d%02d%02d (%s) %s",

                      len_year_max, year+incr_year-decr_year, m, d, filename, s1);

            else

              sprintf(s6, "%0*d%02d%02d (%s)",

                      len_year_max, year+incr_year-decr_year, m, d, filename);

          }

         else

           sprintf(s6, "%0*d%02d%02d %s",

                   len_year_max, year+incr_year-decr_year, m, d, s1);

         /*

            Now compute whether a filler text for a week entry is needed:

              Week 51/0   == 7 chars text "|51/0| "  -> no filler text.

              Week 52/0   == 7 chars text "|52/1| "  -> no filler text.

              Week 53/0   == 7 chars text "|53/0| "  -> no filler text.

              Week 53/1   == 7 chars text "|53/1| "  -> no filler text.

              Week 1...52 == 5 chars text "|nn| "    -> 2 chars filler text.

         */

         if (rc_weekno_flag)

           if (week_number (d, m, year+incr_year-decr_year) <= 0)

             len_fil_wt = 2;

         /*

            Now place the fixed date into the table:

              Only if the previous fixed date is equal the actual fixed date,

              avoid insertation of actual fixed date!

         */

         i = 1;

         if (*rc_elems)

           i = strcmp(s6, rc_elems_table[*rc_elems-1]);

         /*

            Store the constructed "raw" line in `rc_elems_table[]'.

         */

         if (i)

          {

            if ((Uint)*rc_elems >= rc_elems_max)

             {

               /*

                  Resize the `rc_elems_table[]' table.

               */

               rc_elems_max <<= 1;

               if (rc_elems_max*sizeof(char *) > testval)

                 rc_elems_max--;

               rc_elems_table = (char **)my_realloc ((VOID_PTR)rc_elems_table, rc_elems_max*sizeof(char *),

                                                     124, __FILE__, ((long)__LINE__)-1,

                                                     "rc_elems_table[rc_elems_max]", rc_elems_max);

             }

            rc_elems_table[*rc_elems] = (char *)my_malloc (strlen(s6)+1,

                                                           124, __FILE__, ((long)__LINE__)-1,

                                                           "rc_elems_table[rc_elems]", *rc_elems);

            strcpy(rc_elems_table[(*rc_elems)++], s6);

          }

       }

      /*

         Must we construct a 1x2 production of the line?

      */

      if (print_twice > 1)

       {

         if (is_2easter)

          {

            /*

               Precalculate the next date relative to Easter Sunday's date.

            */

            incr_year = 1;

            precomp_date (hn, hwd, &d, &m, year+incr_year, EAster);

          }

         else

           if (is_2dvar)

            {

              /*

                 Precalculate the next date relative to date variable's date

                   and use original date of `dvar', i.e. use buffer of day an month.

              */

              incr_year = 1;

              if (islower(hc))

                (void)precomp_date (hn, hwd, &d_buf, &m_buf, year+incr_year, DVar);

              else

               {

                 y = year + incr_year;

                 (void)precomp_nth_wd (hn, hwd, &hn, &d_buf, &m_buf, &y,

                                       (hc == 'D') ? DAy : WEek);

               }

              d = d_buf;

              m = m_buf;

            }

           else

             /*

                Compute tomorrows date.

             */

             next_date (&d, &m, &year);

         /*

            If the "new" precomputed date is off the year bounds, we have to exit the loop!

         */

         if (year+incr_year > YEAR_MAX)

           print_twice--;

         else

           print_line = TRUE;

       }

    } while (--print_twice);   /* I don't like the GNU-coding scheme for do-whiles */

   year = tmp_year;

}







   LOCAL int

get_number (string)

   char **string;

/*

   Returns the absolute value of a "repeat for N days since..." field or

     "for each N'th day since..." field using the global `s6' text buffer.

*/

{

   register int  i=0;





   if (*string != (char *)NULL)

    {

      (*string)++;

      while (isdigit(**string))

        s6[i++] = *((*string)++);

      s6[i] = '\0';

      /*

         Make sure we return values in range 1...366 or 0 if an error have occured.

      */

      if (i > 3)

        return 0;

      i = atoi(s6);

      if (i > DAY_LAST + 1)

        i = DAY_LAST + 1;

    }



   return i;

}

#endif /* USE_RC */

