/* Version and usage information. usage is used to print */
char *version = "calcdate v2.01, 17 May 88, Gordon A. Runkle, ORI/Calculon\n";
char *usage = "Usage: calcdate mmddyy { -o [-]offset | -d mmddyy }\n\n";
char *prog = "calcdate";
/* External variables for holding results of parsing of date values */
int month_1, day_1, year_1, month_2, day_2, year_2;
/* no_days[0] is for reg yrs, no_days[1] is for leap yrs */
int no_days[2][12] =
{
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
};
/* Test for the proper number of args. */
if (argc != 4)
{
fprintf(stderr, version);
fprintf(stderr, usage);
exit(-1);
}
/* Tests first date for valid format and contents */
if (valid_date(argv[1], 1) != 0)
exit(-1); /* The error message is in the function */
/* Test for an option flag in the second arg */
if (argv[2][0] != '-')
{
fprintf(stderr, usage);
exit(-1);
}
/* Make a decision based on the option */
if (argv[2][1] == 'o')
{
if (off_calc(argv[3]) != 0)
exit(-1);
}
else if (argv[2][1] == 'd')
{
if (valid_date(argv[3], 2) != 0)
exit(-1);
else
{
if (dates_calc() != 0) /* no arg is needed - valid_date */
exit (-1); /* takes care of the dates */
}
}
else
{
fprintf(stderr, usage);
exit(-1);
}
return(0);
}
/***************************************/
valid_date(tst_date, date_flag)
char tst_date[];
int date_flag;
{
extern int month_1, day_1, year_1;
extern int month_2, day_2, year_2;
extern char *prog;
int i, leap_flag, month, day, year;
if (strlen(tst_date) != 6)
{
fprintf(stderr, "%s: date must be entered as mmddyy\n", prog);
return(-1);
}
for (i = 0; i < 6; i++)
if (tst_date[i] < '0' || tst_date[i] > '9')
{
fprintf(stderr, "%s: date must be entered as mmddyy\n", prog);
return(-1);
}
if (day > no_days[leap_flag][month - 1])
{
fprintf(stderr, "%s: invalid day %d\n", prog, day);
return(-1);
}
/* This determines where our carefully-checked values are stored */
if (date_flag == 1)
{
day_1 = day;
month_1 = month;
year_1 = year;
}
else if (date_flag == 2)
{
day_2 = day;
month_2 = month;
year_2 = year;
}
else
{
fprintf(stderr, "%s: unexpected error assigning date values\n", prog);
return(-1);
}
return(0);
}
/***************************************/
off_calc(offset)
char offset[];
{
extern int no_days[2][12];
extern int month_1, day_1, year_1;
extern char *prog;
int atoi();
int i_offset, n_month, n_day, n_year, month_bal;
int i, leap_flag;
char newdate[7];
/* This checks for a valid offset value. Negative values are allowed
and checked for. It stops at the first null. */
for (i = 0; i < 4; i++)
{
if (offset[i] == '\0')
break;
if (i == 0 && offset[i] == '-')
continue;
if (offset[i] < '0' || offset[i] > '9')
{
fprintf(stderr, "%s: offset must be entered as an integer\n", prog);
exit(-1);
}
}
i_offset = atoi(offset);
/* This is the beginning of the neat stuff. I hope it works! */
/* leap year is when =>> year % 4 == 0 */
n_year = year_1; /* the *_1 is used, as this is the value of the */
n_month = month_1; /* first date entered */
n_day = day_1;
if (i_offset >= 0)
{
while (i_offset > 0)
{
if (n_year % 4 == 0)
leap_flag = LEAP;
else
leap_flag = REG;
for (i = 0; i < 7; i++)
if (newdate[i] == ' ')
newdate[i] = '0';
fprintf(stdout, "%s\n", newdate);
return(0);
}
/***************************************/
dates_calc()
{
extern int no_days[2][12];
extern int month_1, day_1, year_1, month_2, day_2, year_2;
int first_rec = 0, curr_offset = 0;
int leap_flag, sign_flag;
int start_day, start_month, start_year, end_day, end_month, end_year;
/****
This section determines which date is later, so that the program
may evaluate the earlier one first. There is a flag set to indicate
what sign the end result should have based on whether the first date
entered is earlier or later than the second.
****/
/* This makes the earlier date be set to start_* */
if (sign_flag == POS)
{
start_day = day_1;
start_month = month_1;
start_year = year_1;
end_day = day_2;
end_month = month_2;
end_year = year_2;
}
else
{
start_day = day_2;
start_month = month_2;
start_year = year_2;
end_day = day_1;
end_month = month_1;
end_year = year_1;
}
/* The calculations below keep incrementing curr_offset and start_* until
start_* == end_* */
for (;;)
{
if (start_year % 4 == 0)
leap_flag = LEAP;
else
leap_flag = REG;
if (first_rec == 0)
{
/* This is for when the month and year start out the same, and
the user just wants the days (ie. 051688 052688 */
if (start_month == end_month && start_year == end_year)
{
curr_offset = end_day - start_day;
break;
}
curr_offset = no_days[leap_flag][start_month - 1] - start_day;
first_rec = 1;
}
else if (start_month == end_month && start_year == end_year)
{
curr_offset += end_day;
break; /* This is the end of it */
}
else
curr_offset += no_days[leap_flag][start_month - 1];
start_month++;
if (start_month > 12)
{
start_month = 1;
start_year++;