Home | History | Annotate | Line # | Download | only in cal
cal.c revision 1.1.1.2
      1      1.1    cgd /*
      2  1.1.1.2  glass  * Copyright (c) 1989, 1993, 1994
      3  1.1.1.2  glass  *	The Regents of the University of California.  All rights reserved.
      4      1.1    cgd  *
      5      1.1    cgd  * This code is derived from software contributed to Berkeley by
      6      1.1    cgd  * Kim Letkeman.
      7      1.1    cgd  *
      8      1.1    cgd  * Redistribution and use in source and binary forms, with or without
      9      1.1    cgd  * modification, are permitted provided that the following conditions
     10      1.1    cgd  * are met:
     11      1.1    cgd  * 1. Redistributions of source code must retain the above copyright
     12      1.1    cgd  *    notice, this list of conditions and the following disclaimer.
     13      1.1    cgd  * 2. Redistributions in binary form must reproduce the above copyright
     14      1.1    cgd  *    notice, this list of conditions and the following disclaimer in the
     15      1.1    cgd  *    documentation and/or other materials provided with the distribution.
     16      1.1    cgd  * 3. All advertising materials mentioning features or use of this software
     17      1.1    cgd  *    must display the following acknowledgement:
     18      1.1    cgd  *	This product includes software developed by the University of
     19      1.1    cgd  *	California, Berkeley and its contributors.
     20      1.1    cgd  * 4. Neither the name of the University nor the names of its contributors
     21      1.1    cgd  *    may be used to endorse or promote products derived from this software
     22      1.1    cgd  *    without specific prior written permission.
     23      1.1    cgd  *
     24      1.1    cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     25      1.1    cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     26      1.1    cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     27      1.1    cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     28      1.1    cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     29      1.1    cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     30      1.1    cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     31      1.1    cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     32      1.1    cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     33      1.1    cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     34      1.1    cgd  * SUCH DAMAGE.
     35      1.1    cgd  */
     36      1.1    cgd 
     37      1.1    cgd #ifndef lint
     38  1.1.1.2  glass static char copyright[] =
     39  1.1.1.2  glass "@(#) Copyright (c) 1989, 1993, 1994\n\
     40  1.1.1.2  glass 	The Regents of the University of California.  All rights reserved.\n";
     41      1.1    cgd #endif /* not lint */
     42      1.1    cgd 
     43      1.1    cgd #ifndef lint
     44  1.1.1.2  glass static char sccsid[] = "@(#)cal.c	8.4 (Berkeley) 4/2/94";
     45      1.1    cgd #endif /* not lint */
     46      1.1    cgd 
     47      1.1    cgd #include <sys/types.h>
     48  1.1.1.2  glass 
     49      1.1    cgd #include <ctype.h>
     50  1.1.1.2  glass #include <err.h>
     51  1.1.1.2  glass #include <stdio.h>
     52  1.1.1.2  glass #include <stdlib.h>
     53  1.1.1.2  glass #include <string.h>
     54  1.1.1.2  glass #include <time.h>
     55  1.1.1.2  glass #include <unistd.h>
     56      1.1    cgd 
     57      1.1    cgd #define	THURSDAY		4		/* for reformation */
     58      1.1    cgd #define	SATURDAY 		6		/* 1 Jan 1 was a Saturday */
     59      1.1    cgd 
     60      1.1    cgd #define	FIRST_MISSING_DAY 	639787		/* 3 Sep 1752 */
     61      1.1    cgd #define	NUMBER_MISSING_DAYS 	11		/* 11 day correction */
     62      1.1    cgd 
     63      1.1    cgd #define	MAXDAYS			42		/* max slots in a month array */
     64      1.1    cgd #define	SPACE			-1		/* used in day array */
     65      1.1    cgd 
     66      1.1    cgd static int days_in_month[2][13] = {
     67      1.1    cgd 	{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
     68      1.1    cgd 	{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
     69      1.1    cgd };
     70      1.1    cgd 
     71      1.1    cgd int sep1752[MAXDAYS] = {
     72      1.1    cgd 	SPACE,	SPACE,	1,	2,	14,	15,	16,
     73      1.1    cgd 	17,	18,	19,	20,	21,	22,	23,
     74      1.1    cgd 	24,	25,	26,	27,	28,	29,	30,
     75      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     76      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     77      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     78      1.1    cgd }, j_sep1752[MAXDAYS] = {
     79      1.1    cgd 	SPACE,	SPACE,	245,	246,	258,	259,	260,
     80      1.1    cgd 	261,	262,	263,	264,	265,	266,	267,
     81      1.1    cgd 	268,	269,	270,	271,	272,	273,	274,
     82      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     83      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     84      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     85      1.1    cgd }, empty[MAXDAYS] = {
     86      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     87      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     88      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     89      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     90      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     91      1.1    cgd 	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,	SPACE,
     92      1.1    cgd };
     93      1.1    cgd 
     94      1.1    cgd char *month_names[12] = {
     95      1.1    cgd 	"January", "February", "March", "April", "May", "June",
     96      1.1    cgd 	"July", "August", "September", "October", "November", "December",
     97      1.1    cgd };
     98      1.1    cgd 
     99      1.1    cgd char *day_headings = " S  M Tu  W Th  F  S";
    100      1.1    cgd char *j_day_headings = "  S   M  Tu   W  Th   F   S";
    101      1.1    cgd 
    102      1.1    cgd /* leap year -- account for gregorian reformation in 1752 */
    103      1.1    cgd #define	leap_year(yr) \
    104      1.1    cgd 	((yr) <= 1752 ? !((yr) % 4) : \
    105      1.1    cgd 	!((yr) % 4) && ((yr) % 100) || !((yr) % 400))
    106      1.1    cgd 
    107      1.1    cgd /* number of centuries since 1700, not inclusive */
    108      1.1    cgd #define	centuries_since_1700(yr) \
    109      1.1    cgd 	((yr) > 1700 ? (yr) / 100 - 17 : 0)
    110      1.1    cgd 
    111      1.1    cgd /* number of centuries since 1700 whose modulo of 400 is 0 */
    112      1.1    cgd #define	quad_centuries_since_1700(yr) \
    113      1.1    cgd 	((yr) > 1600 ? ((yr) - 1600) / 400 : 0)
    114      1.1    cgd 
    115      1.1    cgd /* number of leap years between year 1 and this year, not inclusive */
    116      1.1    cgd #define	leap_years_since_year_1(yr) \
    117      1.1    cgd 	((yr) / 4 - centuries_since_1700(yr) + quad_centuries_since_1700(yr))
    118      1.1    cgd 
    119      1.1    cgd int julian;
    120      1.1    cgd 
    121  1.1.1.2  glass void	ascii_day __P((char *, int));
    122  1.1.1.2  glass void	center __P((char *, int, int));
    123  1.1.1.2  glass void	day_array __P((int, int, int *));
    124  1.1.1.2  glass int	day_in_week __P((int, int, int));
    125  1.1.1.2  glass int	day_in_year __P((int, int, int));
    126  1.1.1.2  glass void	j_yearly __P((int));
    127  1.1.1.2  glass void	monthly __P((int, int));
    128  1.1.1.2  glass void	trim_trailing_spaces __P((char *));
    129  1.1.1.2  glass void	usage __P((void));
    130  1.1.1.2  glass void	yearly __P((int));
    131  1.1.1.2  glass 
    132  1.1.1.2  glass int
    133      1.1    cgd main(argc, argv)
    134      1.1    cgd 	int argc;
    135      1.1    cgd 	char **argv;
    136      1.1    cgd {
    137      1.1    cgd 	struct tm *local_time;
    138  1.1.1.2  glass 	time_t now;
    139      1.1    cgd 	int ch, month, year, yflag;
    140      1.1    cgd 
    141      1.1    cgd 	yflag = 0;
    142      1.1    cgd 	while ((ch = getopt(argc, argv, "jy")) != EOF)
    143      1.1    cgd 		switch(ch) {
    144      1.1    cgd 		case 'j':
    145      1.1    cgd 			julian = 1;
    146      1.1    cgd 			break;
    147      1.1    cgd 		case 'y':
    148      1.1    cgd 			yflag = 1;
    149      1.1    cgd 			break;
    150      1.1    cgd 		case '?':
    151      1.1    cgd 		default:
    152      1.1    cgd 			usage();
    153      1.1    cgd 		}
    154      1.1    cgd 	argc -= optind;
    155      1.1    cgd 	argv += optind;
    156      1.1    cgd 
    157      1.1    cgd 	month = 0;
    158      1.1    cgd 	switch(argc) {
    159      1.1    cgd 	case 2:
    160  1.1.1.2  glass 		if ((month = atoi(*argv++)) < 1 || month > 12)
    161  1.1.1.2  glass 			errx(1, "illegal month value: use 1-12");
    162      1.1    cgd 		/* FALLTHROUGH */
    163      1.1    cgd 	case 1:
    164  1.1.1.2  glass 		if ((year = atoi(*argv)) < 1 || year > 9999)
    165  1.1.1.2  glass 			errx(1, "illegal year value: use 1-9999");
    166      1.1    cgd 		break;
    167      1.1    cgd 	case 0:
    168      1.1    cgd 		(void)time(&now);
    169      1.1    cgd 		local_time = localtime(&now);
    170      1.1    cgd 		year = local_time->tm_year + 1900;
    171      1.1    cgd 		if (!yflag)
    172      1.1    cgd 			month = local_time->tm_mon + 1;
    173      1.1    cgd 		break;
    174      1.1    cgd 	default:
    175      1.1    cgd 		usage();
    176      1.1    cgd 	}
    177      1.1    cgd 
    178      1.1    cgd 	if (month)
    179      1.1    cgd 		monthly(month, year);
    180      1.1    cgd 	else if (julian)
    181      1.1    cgd 		j_yearly(year);
    182      1.1    cgd 	else
    183      1.1    cgd 		yearly(year);
    184      1.1    cgd 	exit(0);
    185      1.1    cgd }
    186      1.1    cgd 
    187      1.1    cgd #define	DAY_LEN		3		/* 3 spaces per day */
    188      1.1    cgd #define	J_DAY_LEN	4		/* 4 spaces per day */
    189      1.1    cgd #define	WEEK_LEN	20		/* 7 * 3 - one space at the end */
    190      1.1    cgd #define	J_WEEK_LEN	27		/* 7 * 4 - one space at the end */
    191      1.1    cgd #define	HEAD_SEP	2		/* spaces between day headings */
    192      1.1    cgd #define	J_HEAD_SEP	2
    193      1.1    cgd 
    194  1.1.1.2  glass void
    195      1.1    cgd monthly(month, year)
    196      1.1    cgd 	int month, year;
    197      1.1    cgd {
    198  1.1.1.2  glass 	int col, row, len, days[MAXDAYS];
    199  1.1.1.2  glass 	char *p, lineout[30];
    200      1.1    cgd 
    201      1.1    cgd 	day_array(month, year, days);
    202      1.1    cgd 	len = sprintf(lineout, "%s %d", month_names[month - 1], year);
    203      1.1    cgd 	(void)printf("%*s%s\n%s\n",
    204      1.1    cgd 	    ((julian ? J_WEEK_LEN : WEEK_LEN) - len) / 2, "",
    205      1.1    cgd 	    lineout, julian ? j_day_headings : day_headings);
    206      1.1    cgd 	for (row = 0; row < 6; row++) {
    207      1.1    cgd 		for (col = 0, p = lineout; col < 7; col++,
    208      1.1    cgd 		    p += julian ? J_DAY_LEN : DAY_LEN)
    209      1.1    cgd 			ascii_day(p, days[row * 7 + col]);
    210  1.1.1.2  glass 		*p = '\0';
    211      1.1    cgd 		trim_trailing_spaces(lineout);
    212      1.1    cgd 		(void)printf("%s\n", lineout);
    213      1.1    cgd 	}
    214      1.1    cgd }
    215      1.1    cgd 
    216  1.1.1.2  glass void
    217      1.1    cgd j_yearly(year)
    218      1.1    cgd 	int year;
    219      1.1    cgd {
    220  1.1.1.2  glass 	int col, *dp, i, month, row, which_cal;
    221      1.1    cgd 	int days[12][MAXDAYS];
    222  1.1.1.2  glass 	char *p, lineout[80];
    223      1.1    cgd 
    224      1.1    cgd 	(void)sprintf(lineout, "%d", year);
    225      1.1    cgd 	center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0);
    226      1.1    cgd 	(void)printf("\n\n");
    227      1.1    cgd 	for (i = 0; i < 12; i++)
    228      1.1    cgd 		day_array(i + 1, year, days[i]);
    229      1.1    cgd 	(void)memset(lineout, ' ', sizeof(lineout) - 1);
    230      1.1    cgd 	lineout[sizeof(lineout) - 1] = '\0';
    231      1.1    cgd 	for (month = 0; month < 12; month += 2) {
    232      1.1    cgd 		center(month_names[month], J_WEEK_LEN, J_HEAD_SEP);
    233      1.1    cgd 		center(month_names[month + 1], J_WEEK_LEN, 0);
    234      1.1    cgd 		(void)printf("\n%s%*s%s\n", j_day_headings, J_HEAD_SEP, "",
    235      1.1    cgd 		    j_day_headings);
    236      1.1    cgd 		for (row = 0; row < 6; row++) {
    237      1.1    cgd 			for (which_cal = 0; which_cal < 2; which_cal++) {
    238      1.1    cgd 				p = lineout + which_cal * (J_WEEK_LEN + 2);
    239      1.1    cgd 				dp = &days[month + which_cal][row * 7];
    240      1.1    cgd 				for (col = 0; col < 7; col++, p += J_DAY_LEN)
    241      1.1    cgd 					ascii_day(p, *dp++);
    242      1.1    cgd 			}
    243  1.1.1.2  glass 			*p = '\0';
    244      1.1    cgd 			trim_trailing_spaces(lineout);
    245      1.1    cgd 			(void)printf("%s\n", lineout);
    246      1.1    cgd 		}
    247      1.1    cgd 	}
    248      1.1    cgd 	(void)printf("\n");
    249      1.1    cgd }
    250      1.1    cgd 
    251  1.1.1.2  glass void
    252      1.1    cgd yearly(year)
    253      1.1    cgd 	int year;
    254      1.1    cgd {
    255  1.1.1.2  glass 	int col, *dp, i, month, row, which_cal;
    256      1.1    cgd 	int days[12][MAXDAYS];
    257  1.1.1.2  glass 	char *p, lineout[80];
    258      1.1    cgd 
    259      1.1    cgd 	(void)sprintf(lineout, "%d", year);
    260      1.1    cgd 	center(lineout, WEEK_LEN * 3 + HEAD_SEP * 2, 0);
    261      1.1    cgd 	(void)printf("\n\n");
    262      1.1    cgd 	for (i = 0; i < 12; i++)
    263      1.1    cgd 		day_array(i + 1, year, days[i]);
    264      1.1    cgd 	(void)memset(lineout, ' ', sizeof(lineout) - 1);
    265      1.1    cgd 	lineout[sizeof(lineout) - 1] = '\0';
    266      1.1    cgd 	for (month = 0; month < 12; month += 3) {
    267      1.1    cgd 		center(month_names[month], WEEK_LEN, HEAD_SEP);
    268      1.1    cgd 		center(month_names[month + 1], WEEK_LEN, HEAD_SEP);
    269      1.1    cgd 		center(month_names[month + 2], WEEK_LEN, 0);
    270      1.1    cgd 		(void)printf("\n%s%*s%s%*s%s\n", day_headings, HEAD_SEP,
    271      1.1    cgd 		    "", day_headings, HEAD_SEP, "", day_headings);
    272      1.1    cgd 		for (row = 0; row < 6; row++) {
    273      1.1    cgd 			for (which_cal = 0; which_cal < 3; which_cal++) {
    274      1.1    cgd 				p = lineout + which_cal * (WEEK_LEN + 2);
    275      1.1    cgd 				dp = &days[month + which_cal][row * 7];
    276      1.1    cgd 				for (col = 0; col < 7; col++, p += DAY_LEN)
    277      1.1    cgd 					ascii_day(p, *dp++);
    278      1.1    cgd 			}
    279  1.1.1.2  glass 			*p = '\0';
    280      1.1    cgd 			trim_trailing_spaces(lineout);
    281      1.1    cgd 			(void)printf("%s\n", lineout);
    282      1.1    cgd 		}
    283      1.1    cgd 	}
    284      1.1    cgd 	(void)printf("\n");
    285      1.1    cgd }
    286      1.1    cgd 
    287      1.1    cgd /*
    288      1.1    cgd  * day_array --
    289      1.1    cgd  *	Fill in an array of 42 integers with a calendar.  Assume for a moment
    290      1.1    cgd  *	that you took the (maximum) 6 rows in a calendar and stretched them
    291      1.1    cgd  *	out end to end.  You would have 42 numbers or spaces.  This routine
    292      1.1    cgd  *	builds that array for any month from Jan. 1 through Dec. 9999.
    293      1.1    cgd  */
    294  1.1.1.2  glass void
    295      1.1    cgd day_array(month, year, days)
    296      1.1    cgd 	int month, year;
    297  1.1.1.2  glass 	int *days;
    298      1.1    cgd {
    299  1.1.1.2  glass 	int day, dw, dm;
    300      1.1    cgd 
    301      1.1    cgd 	if (month == 9 && year == 1752) {
    302  1.1.1.2  glass 		memmove(days,
    303  1.1.1.2  glass 			julian ? j_sep1752 : sep1752, MAXDAYS * sizeof(int));
    304      1.1    cgd 		return;
    305      1.1    cgd 	}
    306  1.1.1.2  glass 	memmove(days, empty, MAXDAYS * sizeof(int));
    307      1.1    cgd 	dm = days_in_month[leap_year(year)][month];
    308      1.1    cgd 	dw = day_in_week(1, month, year);
    309      1.1    cgd 	day = julian ? day_in_year(1, month, year) : 1;
    310      1.1    cgd 	while (dm--)
    311      1.1    cgd 		days[dw++] = day++;
    312      1.1    cgd }
    313      1.1    cgd 
    314      1.1    cgd /*
    315      1.1    cgd  * day_in_year --
    316      1.1    cgd  *	return the 1 based day number within the year
    317      1.1    cgd  */
    318  1.1.1.2  glass int
    319      1.1    cgd day_in_year(day, month, year)
    320  1.1.1.2  glass 	int day, month, year;
    321      1.1    cgd {
    322  1.1.1.2  glass 	int i, leap;
    323      1.1    cgd 
    324      1.1    cgd 	leap = leap_year(year);
    325      1.1    cgd 	for (i = 1; i < month; i++)
    326      1.1    cgd 		day += days_in_month[leap][i];
    327  1.1.1.2  glass 	return (day);
    328      1.1    cgd }
    329      1.1    cgd 
    330      1.1    cgd /*
    331      1.1    cgd  * day_in_week
    332      1.1    cgd  *	return the 0 based day number for any date from 1 Jan. 1 to
    333      1.1    cgd  *	31 Dec. 9999.  Assumes the Gregorian reformation eliminates
    334      1.1    cgd  *	3 Sep. 1752 through 13 Sep. 1752.  Returns Thursday for all
    335      1.1    cgd  *	missing days.
    336      1.1    cgd  */
    337  1.1.1.2  glass int
    338      1.1    cgd day_in_week(day, month, year)
    339      1.1    cgd 	int day, month, year;
    340      1.1    cgd {
    341      1.1    cgd 	long temp;
    342      1.1    cgd 
    343      1.1    cgd 	temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1)
    344      1.1    cgd 	    + day_in_year(day, month, year);
    345      1.1    cgd 	if (temp < FIRST_MISSING_DAY)
    346  1.1.1.2  glass 		return ((temp - 1 + SATURDAY) % 7);
    347      1.1    cgd 	if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS))
    348  1.1.1.2  glass 		return (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7);
    349  1.1.1.2  glass 	return (THURSDAY);
    350      1.1    cgd }
    351      1.1    cgd 
    352  1.1.1.2  glass void
    353      1.1    cgd ascii_day(p, day)
    354  1.1.1.2  glass 	char *p;
    355  1.1.1.2  glass 	int day;
    356      1.1    cgd {
    357  1.1.1.2  glass 	int display, val;
    358      1.1    cgd 	static char *aday[] = {
    359      1.1    cgd 		"",
    360      1.1    cgd 		" 1", " 2", " 3", " 4", " 5", " 6", " 7",
    361      1.1    cgd 		" 8", " 9", "10", "11", "12", "13", "14",
    362      1.1    cgd 		"15", "16", "17", "18", "19", "20", "21",
    363      1.1    cgd 		"22", "23", "24", "25", "26", "27", "28",
    364      1.1    cgd 		"29", "30", "31",
    365      1.1    cgd 	};
    366      1.1    cgd 
    367      1.1    cgd 	if (day == SPACE) {
    368      1.1    cgd 		memset(p, ' ', julian ? J_DAY_LEN : DAY_LEN);
    369      1.1    cgd 		return;
    370      1.1    cgd 	}
    371      1.1    cgd 	if (julian) {
    372      1.1    cgd 		if (val = day / 100) {
    373      1.1    cgd 			day %= 100;
    374      1.1    cgd 			*p++ = val + '0';
    375      1.1    cgd 			display = 1;
    376      1.1    cgd 		} else {
    377      1.1    cgd 			*p++ = ' ';
    378      1.1    cgd 			display = 0;
    379      1.1    cgd 		}
    380      1.1    cgd 		val = day / 10;
    381      1.1    cgd 		if (val || display)
    382      1.1    cgd 			*p++ = val + '0';
    383      1.1    cgd 		else
    384      1.1    cgd 			*p++ = ' ';
    385      1.1    cgd 		*p++ = day % 10 + '0';
    386      1.1    cgd 	} else {
    387      1.1    cgd 		*p++ = aday[day][0];
    388      1.1    cgd 		*p++ = aday[day][1];
    389      1.1    cgd 	}
    390      1.1    cgd 	*p = ' ';
    391      1.1    cgd }
    392      1.1    cgd 
    393  1.1.1.2  glass void
    394      1.1    cgd trim_trailing_spaces(s)
    395  1.1.1.2  glass 	char *s;
    396      1.1    cgd {
    397  1.1.1.2  glass 	char *p;
    398      1.1    cgd 
    399  1.1.1.2  glass 	for (p = s; *p; ++p)
    400  1.1.1.2  glass 		continue;
    401  1.1.1.2  glass 	while (p > s && isspace(*--p))
    402  1.1.1.2  glass 		continue;
    403      1.1    cgd 	if (p > s)
    404      1.1    cgd 		++p;
    405      1.1    cgd 	*p = '\0';
    406      1.1    cgd }
    407      1.1    cgd 
    408  1.1.1.2  glass void
    409      1.1    cgd center(str, len, separate)
    410      1.1    cgd 	char *str;
    411  1.1.1.2  glass 	int len;
    412      1.1    cgd 	int separate;
    413      1.1    cgd {
    414  1.1.1.2  glass 
    415      1.1    cgd 	len -= strlen(str);
    416      1.1    cgd 	(void)printf("%*s%s%*s", len / 2, "", str, len / 2 + len % 2, "");
    417      1.1    cgd 	if (separate)
    418      1.1    cgd 		(void)printf("%*s", separate, "");
    419      1.1    cgd }
    420      1.1    cgd 
    421  1.1.1.2  glass void
    422      1.1    cgd usage()
    423      1.1    cgd {
    424  1.1.1.2  glass 
    425      1.1    cgd 	(void)fprintf(stderr, "usage: cal [-jy] [[month] year]\n");
    426      1.1    cgd 	exit(1);
    427      1.1    cgd }
    428