atifaziz / NCrontab

Crontab for .NET

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Replace "lablel" and "goto" in CrontabSchedule.cs (no issue)

mserafym opened this issue · comments

RetryDayMonth:
if (day == nil)
{
second = seconds.GetFirst();
minute = _minutes.GetFirst();
hour = _hours.GetFirst();
day = _days.GetFirst();
month++;
}
else if (day > baseDay)
{
second = seconds.GetFirst();
minute = _minutes.GetFirst();
hour = _hours.GetFirst();
}
//
// Month
//
month = _months.Next(month);
if (month == nil)
{
second = seconds.GetFirst();
minute = _minutes.GetFirst();
hour = _hours.GetFirst();
day = _days.GetFirst();
month = _months.GetFirst();
year++;
}
else if (month > baseMonth)
{
second = seconds.GetFirst();
minute = _minutes.GetFirst();
hour = _hours.GetFirst();
day = _days.GetFirst();
}
//
// Stop processing when year is too large for the datetime or calendar
// object. Otherwise we would get an exception.
//
if (year > Calendar.MaxSupportedDateTime.Year)
return null;
//
// The day field in a cron expression spans the entire range of days
// in a month, which is from 1 to 31. However, the number of days in
// a month tend to be variable depending on the month (and the year
// in case of February). So a check is needed here to see if the
// date is a border case. If the day happens to be beyond 28
// (meaning that we're dealing with the suspicious range of 29-31)
// and the date part has changed then we need to determine whether
// the day still makes sense for the given year and month. If the
// day is beyond the last possible value, then the day/month part
// for the schedule is re-evaluated. So an expression like "0 0
// 15,31 * *" will yield the following sequence starting on midnight
// of Jan 1, 2000:
//
// Jan 15, Jan 31, Feb 15, Mar 15, Apr 15, Apr 31, ...
//
var dateChanged = day != baseDay || month != baseMonth || year != baseYear;
if (day > 28 && dateChanged && day > Calendar.GetDaysInMonth(year, month))
{
if (year >= endYear && month >= endMonth && day >= endDay)
return endTime;
day = nil;
goto RetryDayMonth;
}

new code (start with 285):

        /**/ while(true)
        {
            if (day == nil)
            {
                second = seconds.GetFirst();
                minute = _minutes.GetFirst();
                hour = _hours.GetFirst();
                day = _days.GetFirst();
                month++;
            }
            else if (day > baseDay)
            {
                second = seconds.GetFirst();
                minute = _minutes.GetFirst();
               hour = _hours.GetFirst();
            }

            //
            // Month
            //

            month = _months.Next(month);

            if (month == nil)
            {
                second = seconds.GetFirst();
                minute = _minutes.GetFirst();
                hour = _hours.GetFirst();
                day = _days.GetFirst();
                month = _months.GetFirst();
                year++;
            }
            else if (month > baseMonth)
            {
                second = seconds.GetFirst();
                minute = _minutes.GetFirst();
                hour = _hours.GetFirst();
                day = _days.GetFirst();
            }

            //
            // Stop processing when year is too large for the datetime or calendar
            // object. Otherwise we would get an exception.
            //

            if (year > Calendar.MaxSupportedDateTime.Year)
                return null;

            //
            // The day field in a cron expression spans the entire range of days
            // in a month, which is from 1 to 31. However, the number of days in
            // a month tend to be variable depending on the month (and the year
            // in case of February). So a check is needed here to see if the
            // date is a border case. If the day happens to be beyond 28
            // (meaning that we're dealing with the suspicious range of 29-31)
            // and the date part has changed then we need to determine whether
            // the day still makes sense for the given year and month. If the
            // day is beyond the last possible value, then the day/month part
            // for the schedule is re-evaluated. So an expression like "0 0
            // 15,31 * *" will yield the following sequence starting on midnight
            // of Jan 1, 2000:
            //
            //  Jan 15, Jan 31, Feb 15, Mar 15, Apr 15, Apr 31, ...
            //

            var dateChanged = day != baseDay || month != baseMonth || year != baseYear;

            if (day > 28 && dateChanged && day > Calendar.GetDaysInMonth(year, month))
            {
                if (year >= endYear && month >= endMonth && day >= endDay)
                    return endTime;

                day = nil;
                continue;
             }
         break;
   } /**/

(edited by @atifaziz to fix code formatting issues with the original post)

The very exceptional use of goto here is completely intentional. An infinite while-loop with a flow continuation and break statement doesn't tell you much about what's going on, especially because the loop body is large. A goto with a clearly named label (telling you that it's going to jump to a point where the day and month computation will be retried) on the other hand does seem more meaningful.

As this is a non-issue, I'm going to close it.

Thank you for response and the explanation! Now I understood the point. Most likely, I'm just "afraid" of goto