⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cal.c

📁 操作系统源代码
💻 C
字号:
/* cal - print a calendar		Author: Maritn Minow */#include <stdlib.h>#include <string.h>#include <stdio.h>#define do3months	domonth#define	IO_SUCCESS	0	/* Unix definitions		 */#define	IO_ERROR	1#define	EOS	0#define	ENTRY_SIZE	3	/* 3 bytes per value		 */#define DAYS_PER_WEEK	7	/* Sunday, etc.			 */#define	WEEKS_PER_MONTH	6	/* Max. weeks in a month	 */#define	MONTHS_PER_LINE	3	/* Three months across		 */#define	MONTH_SPACE	3	/* Between each month		 */char *badarg = {"Bad argument\n"};char *how = {"Usage: cal [month] year\n"};/* Calendar() stuffs data into layout[], * output() copies from layout[] to outline[], (then trims blanks). */char layout[MONTHS_PER_LINE][WEEKS_PER_MONTH][DAYS_PER_WEEK][ENTRY_SIZE];char outline[(MONTHS_PER_LINE * DAYS_PER_WEEK * ENTRY_SIZE)       + (MONTHS_PER_LINE * MONTH_SPACE)       + 1];char *weekday = " S  M Tu  W Th  F  S";char *monthname[] = {	     "???",		/* No month 0	 */	     "Jan", "Feb", "Mar", "Apr", "May", "Jun",	     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void doyear, (int year));_PROTOTYPE(void domonth, (int year, int month));_PROTOTYPE(void output, (int nmonths));_PROTOTYPE(void calendar, (int year, int month, int indx));_PROTOTYPE(void usage, (char *s));_PROTOTYPE(int date, (int year, int month, int week, int wday));_PROTOTYPE(void setmonth, (int year, int month));_PROTOTYPE(int getdate, (int week, int wday));_PROTOTYPE(static int Jan1, (int year));int main(argc, argv)int argc;char *argv[];{  register int year;  register int arg1val;  int arg1len;  int arg2val;  if (argc <= 1) {	usage(how);  } else {	arg1val = atoi(argv[1]);	arg1len = strlen(argv[1]);	if (argc == 2) {		/* Only one argument, if small, it's a month.  If		 * large, it's a year.  Note: cal		0082	Year		 * 0082 cal		82	Year 0082 */		if (arg1len <= 2 && arg1val <= 12)			do3months(year, arg1val);		else			doyear(arg1val);	} else {		/* Two arguments, allow 1980 12 or 12 1980 */		arg2val = atoi(argv[2]);		if (arg1len > 2)			do3months(arg1val, arg2val);		else			do3months(arg2val, arg1val);	}  }  return(IO_SUCCESS);}void doyear(year)int year;/* Print the calendar for an entire year. */{  register int month;  if (year < 1 || year > 9999) usage(badarg);  if (year < 100)	printf("\n\n\n                                 00%2d\n\n", year);  else	printf("\n\n\n%35d\n\n", year);  for (month = 1; month <= 12; month += MONTHS_PER_LINE) {	printf("%12s%23s%23s\n",	       monthname[month],	       monthname[month + 1],	       monthname[month + 2]);	printf("%s   %s   %s\n", weekday, weekday, weekday);	calendar(year, month + 0, 0);	calendar(year, month + 1, 1);	calendar(year, month + 2, 2);	output(3);#if MONTHS_PER_LINE != 3#error  "the above will not work"#endif  }  printf("\n\n\n");}void domonth(year, month)int year;int month;/* Do one specific month -- note: no longer used */{  if (year < 1 || year > 9999) usage(badarg);  if (month <= 0 || month > 12) usage(badarg);  printf("%9s%5d\n\n%s\n", monthname[month], year, weekday);  calendar(year, month, 0);  output(1);  printf("\n\n");}void output(nmonths)int nmonths;			/* Number of months to do	 *//* Clean up and output the text. */{  register int week;  register int month;  register char *outp;  int i;  char tmpbuf[21], *p;  for (week = 0; week < WEEKS_PER_MONTH; week++) {	outp = outline;	for (month = 0; month < nmonths; month++) {		/* The -1 in the following removes the unwanted		 * leading blank from the entry for Sunday. */		p = &layout[month][week][0][1];		for (i = 0; i < 20; i++) tmpbuf[i] = *p++;		tmpbuf[20] = 0;		sprintf(outp, "%s   ", tmpbuf);		outp += (DAYS_PER_WEEK * ENTRY_SIZE) + MONTH_SPACE - 1;	}	while (outp > outline && outp[-1] == ' ') outp--;	*outp = EOS;	printf("%s\n", outline);  }}void calendar(year, month, indx)int year;int month;int indx;			/* Which of the three months		 *//* Actually build the calendar for this month. */{  register char *tp;  int week;  register int wday;  register int today;  setmonth(year, month);  for (week = 0; week < WEEKS_PER_MONTH; week++) {	for (wday = 0; wday < DAYS_PER_WEEK; wday++) {		tp = &layout[indx][week][wday][0];		*tp++ = ' ';		today = getdate(week, wday);		if (today <= 0) {			*tp++ = ' ';			*tp++ = ' ';		} else if (today < 10) {			*tp++ = ' ';			*tp = (today + '0');		} else {			*tp++ = (today / 10) + '0';			*tp = (today % 10) + '0';		}	}  }}void usage(s)char *s;{/* Fatal parameter error. */  fprintf(stderr, "%s", s);  exit(IO_ERROR);}/* Calendar routines, intended for eventual porting to TeX * * date(year, month, week, wday) *	Returns the date on this week (0 is first, 5 last possible) *	and day of the week (Sunday == 0) *	Note: January is month 1. * * setmonth(year, month) *	Parameters are as above, sets getdate() for this month. * * int * getdate(week, wday) *	Parameters are as above, uses the data set by setmonth() *//* This structure is used to pass data between setmonth() and getdate(). * It needs considerable expansion if the Julian->Gregorian change is * to be extended to other countries. */static struct {  int this_month;		/* month number used in 1752 checking	 */  int feb;			/* Days in February for this month	 */  int sept;			/* Days in September for this month	 */  int days_in_month;		/* Number of days in this month		 */  int dow_first;		/* Day of week of the 1st day in month	 */} info;static int day_month[] = {	/* 30 days hath September...		 */		  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};int date(year, month, week, wday)int year;			/* Calendar date being computed		 */int month;			/* January == 1				 */int week;			/* Week in the month 0..5 inclusive	 */int wday;			/* Weekday, Sunday == 0			 *//* Return the date of the month that fell on this week and weekday. * Return zero if it's out of range. */{  setmonth(year, month);  return(getdate(week, wday));}void setmonth(year, month)int year;			/* Year to compute		 */int month;			/* Month, January is month 1	 *//* Setup the parameters needed to compute this month * (stored in the info structure). */{  register int i;  if (month < 1 || month > 12) {/* Verify caller's parameters	 */	info.days_in_month = 0;	/* Garbage flag			 */	return;  }  info.this_month = month;	/* used in 1752	checking	 */  info.dow_first = Jan1(year);	/* Day of January 1st for now	 */  info.feb = 29;		/* Assume leap year		 */  info.sept = 30;		/* Assume normal year		 */  /* Determine whether it's an ordinary year, a leap year or the   * magical calendar switch year of 1752. */  switch ((Jan1(year + 1) + 7 - info.dow_first) % 7) {      case 1:			/* Not a leap year		 */	info.feb = 28;      case 2:			/* Ordinary leap year		 */	break;      default:			/* The magical moment arrives	 */	info.sept = 19;		/* 19 days hath September	 */	break;  }  info.days_in_month =	(month == 2) ? info.feb	: (month == 9) ? info.sept	: day_month[month];  for (i = 1; i < month; i++) {	switch (i) {		/* Special months?		 */	    case 2:		/* February			 */		info.dow_first += info.feb;		break;	    case 9:	info.dow_first += info.sept;	break;	    default:		info.dow_first += day_month[i];		break;	}  }  info.dow_first %= 7;		/* Now it's Sunday to Saturday	 */}int getdate(week, wday)int week;int wday;{  register int today;  /* Get a first guess at today's date and make sure it's in range. */  today = (week * 7) + wday - info.dow_first + 1;  if (today <= 0 || today > info.days_in_month)	return(0);  else if (info.sept == 19 && info.this_month == 9	 && today >= 3)		/* The magical month?	 */	return(today + 11);	/* If so, some dates changed	 */  else				/* Otherwise,			 */	return(today);		/* Return the date		 */}static int Jan1(year)int year;/* Return day of the week for Jan 1 of the specified year. */{  register int day;  day = year + 4 + ((year + 3) / 4);	/* Julian Calendar	 */  if (year > 1800) {		/* If it's recent, do	 */	day -= ((year - 1701) / 100);	/* Clavian correction	 */	day += ((year - 1601) / 400);	/* Gregorian correction	 */  }  if (year > 1752)		/* Adjust for Gregorian	 */	day += 3;		/* calendar		 */  return(day % 7);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -