📄 cal.c
字号:
if (wcswidth(wd_wc,10) < 2) { wcscat(day_headings_wc, L" "); wcscat(j_day_headings_wc, L" "); } wcsncat(day_headings_wc,wd_wc,2); wcsncat(j_day_headings_wc,wd_wc,3); wcscat(day_headings_wc, L" "); wcscat(j_day_headings_wc, L" ");#else sprintf(eos(day_headings), "%2.2s ", weekday(wd)); sprintf(eos(j_day_headings), "%3.3s ", weekday(wd));#endif }#ifdef ENABLE_WIDECHAR wcstombs(day_headings,day_headings_wc,sizeof(day_headings)); wcstombs(j_day_headings,j_day_headings_wc,sizeof(j_day_headings));#endif trim_trailing_spaces(day_headings); trim_trailing_spaces(j_day_headings);#undef weekday for (i = 0; i < 12; i++) {#ifdef HAVE_langinfo_h full_month[i] = nl_langinfo(MON_1+i);#else full_month[i] = _time_info->full_month[i];#endif }}voiddo_monthly(int day, int month, int year, struct fmt_st *out) { int col, row, len, days[MAXDAYS]; char *p, lineout[FMT_ST_CHARS]; int width = (julian ? J_WEEK_LEN : WEEK_LEN) - 1; day_array(day, month, year, days); /* * %s is the month name, %d the year number. * you can change the order and/or add something here; eg for * Basque the translation should be: "%2$dko %1$s", and * the Vietnamese should be "%s na(m %d", etc. */ len = sprintf(lineout, _("%s %d"), full_month[month - 1], year); center_str(lineout, out->s[0], SIZE(out->s[0]), width); sprintf(out->s[1],"%s", julian ? j_day_headings : day_headings); for (row = 0; row < 6; row++) { for (col = 0, p = lineout; col < 7; col++) p = ascii_day(p, days[row * 7 + col]); *p = '\0'; trim_trailing_spaces(lineout); sprintf(out->s[row+2], "%s", lineout); }}voidmonthly(int day, int month, int year) { int i; struct fmt_st out; do_monthly(day, month, year, &out); for (i = 0; i < FMT_ST_LINES; i++) {#if defined(HAVE_ncurses) || defined(HAVE_termcap) my_putstring(out.s[i]);putchar('\n');#else puts(out.s[i]);#endif }}voidmonthly3(int day, int month, int year) { char lineout[FMT_ST_CHARS]; int i; int width; struct fmt_st out_prev; struct fmt_st out_curm; struct fmt_st out_next; int prev_month, prev_year; int next_month, next_year; if (month == 1) { prev_month = 12; prev_year = year - 1; } else { prev_month = month - 1; prev_year = year; } if (month == 12) { next_month = 1; next_year = year + 1; } else { next_month = month + 1; next_year = year; } do_monthly(day, prev_month, prev_year, &out_prev); do_monthly(day, month, year, &out_curm); do_monthly(day, next_month, next_year, &out_next); width = (julian ? J_WEEK_LEN : WEEK_LEN) -1; for (i = 0; i < 2; i++) printf("%s %s %s\n", out_prev.s[i], out_curm.s[i], out_next.s[i]); for (i = 2; i < FMT_ST_LINES; i++) { snprintf(lineout, SIZE(lineout), "%-*s %-*s %-*s\n", width, out_prev.s[i], width, out_curm.s[i], width, out_next.s[i]);#if defined(HAVE_ncurses) || defined(HAVE_termcap) my_putstring(lineout);#else fputs(lineout,stdout);#endif }}voidj_yearly(int day, int year) { int col, *dp, i, month, row, which_cal; int days[12][MAXDAYS]; char *p, lineout[80]; sprintf(lineout, "%d", year); center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0); printf("\n\n"); for (i = 0; i < 12; i++) day_array(day, i + 1, year, days[i]); memset(lineout, ' ', sizeof(lineout) - 1); lineout[sizeof(lineout) - 1] = '\0'; for (month = 0; month < 12; month += 2) { center(full_month[month], J_WEEK_LEN, J_HEAD_SEP); center(full_month[month + 1], J_WEEK_LEN, 0); printf("\n%s%*s %s\n", j_day_headings, J_HEAD_SEP, "", j_day_headings); for (row = 0; row < 6; row++) { p = lineout; for (which_cal = 0; which_cal < 2; which_cal++) { dp = &days[month + which_cal][row * 7]; for (col = 0; col < 7; col++) p = ascii_day(p, *dp++); p += sprintf(p, " "); } *p = '\0'; trim_trailing_spaces(lineout);#if defined(HAVE_ncurses) || defined(HAVE_termcap) my_putstring(lineout);putchar('\n');#else puts(lineout);#endif } } printf("\n");}voidyearly(int day, int year) { int col, *dp, i, month, row, which_cal; int days[12][MAXDAYS]; char *p, lineout[100]; sprintf(lineout, "%d", year); center(lineout, WEEK_LEN * 3 + HEAD_SEP * 2, 0); printf("\n\n"); for (i = 0; i < 12; i++) day_array(day, i + 1, year, days[i]); memset(lineout, ' ', sizeof(lineout) - 1); lineout[sizeof(lineout) - 1] = '\0'; for (month = 0; month < 12; month += 3) { center(full_month[month], WEEK_LEN, HEAD_SEP); center(full_month[month + 1], WEEK_LEN, HEAD_SEP); center(full_month[month + 2], WEEK_LEN, 0); printf("\n%s%*s %s%*s %s\n", day_headings, HEAD_SEP, "", day_headings, HEAD_SEP, "", day_headings); for (row = 0; row < 6; row++) { p = lineout; for (which_cal = 0; which_cal < 3; which_cal++) { dp = &days[month + which_cal][row * 7]; for (col = 0; col < 7; col++) p = ascii_day(p, *dp++); p += sprintf(p, " "); } *p = '\0'; trim_trailing_spaces(lineout);#if defined(HAVE_ncurses) || defined(HAVE_termcap) my_putstring(lineout);putchar('\n');#else puts(lineout);#endif } } printf("\n");}/* * day_array -- * Fill in an array of 42 integers with a calendar. Assume for a moment * that you took the (maximum) 6 rows in a calendar and stretched them * out end to end. You would have 42 numbers or spaces. This routine * builds that array for any month from Jan. 1 through Dec. 9999. */voidday_array(int day, int month, int year, int *days) { int julday, daynum, dw, dm; int *d_sep1752; if (month == 9 && year == 1752) { d_sep1752 = julian ? j_sep1752 : sep1752; memcpy(days, d_sep1752 + week1stday, MAXDAYS * sizeof(int)); return; } memcpy(days, empty, MAXDAYS * sizeof(int)); dm = days_in_month[leap_year(year)][month]; dw = (day_in_week(1, month, year) - week1stday + 7) % 7; julday = day_in_year(1, month, year); daynum = julian ? julday : 1; while (dm--) { days[dw] = daynum++; if (julday++ == day) days[dw] |= TODAY_FLAG; dw++; }}/* * day_in_year -- * return the 1 based day number within the year */intday_in_year(int day, int month, int year) { int i, leap; leap = leap_year(year); for (i = 1; i < month; i++) day += days_in_month[leap][i]; return day;}/* * day_in_week * return the 0 based day number for any date from 1 Jan. 1 to * 31 Dec. 9999. Assumes the Gregorian reformation eliminates * 3 Sep. 1752 through 13 Sep. 1752. Returns Thursday for all * missing days. */intday_in_week(int day, int month, int year) { long temp; temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1) + day_in_year(day, month, year); if (temp < FIRST_MISSING_DAY) return ((temp - 1 + SATURDAY) % 7); if (temp >= (FIRST_MISSING_DAY + NUMBER_MISSING_DAYS)) return (((temp - 1 + SATURDAY) - NUMBER_MISSING_DAYS) % 7); return (THURSDAY);}char *ascii_day(char *p, int day) { int display, val; int highlight = 0; static char *aday[] = { "", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", }; if (day == SPACE) { int len = julian ? J_DAY_LEN : DAY_LEN; memset(p, ' ', len); return p+len; } if (day & TODAY_FLAG) { day &= ~TODAY_FLAG; p += sprintf(p, Senter); highlight = 1; } if (julian) { if ((val = day / 100)) { day %= 100; *p++ = val + '0'; display = 1; } else { *p++ = ' '; display = 0; } val = day / 10; if (val || display) *p++ = val + '0'; else *p++ = ' '; *p++ = day % 10 + '0'; } else { *p++ = aday[day][0]; *p++ = aday[day][1]; } if (highlight) p += sprintf(p, Sexit); *p++ = ' '; return p;}voidtrim_trailing_spaces(s) char *s;{ char *p; for (p = s; *p; ++p) continue; while (p > s && isspace(*--p)) continue; if (p > s) ++p; *p = '\0';}/* * Center string, handling multibyte characters appropriately. * In addition if the string is too large for the width it's truncated. */voidcenter_str(const char* src, char* dest, size_t dest_size, int width){#ifdef ENABLE_WIDECHAR wchar_t str_wc[FMT_ST_CHARS];#endif char str[FMT_ST_CHARS]; const char* str_to_print=src; int len, spaces, wide_char_enabled=0; len = strlen(src);#ifdef ENABLE_WIDECHAR if (mbstowcs(str_wc, src, FMT_ST_CHARS) > 0) { wide_char_enabled = 1; len = wcswidth(str_wc, SIZE(str_wc)); }#endif if (len > width) { str_to_print=str; if (wide_char_enabled) {#ifdef ENABLE_WIDECHAR str_wc[width]=L'\0'; wcstombs(str, str_wc, SIZE(str));#endif } else { strncpy(str, src, SIZE(str)); str[width]='\0'; } } spaces = width - len; spaces = ( spaces < 0 ? 0 : spaces ); snprintf(dest, dest_size, "%*s%s%*s", spaces / 2, "", str_to_print, spaces / 2 + spaces % 2, "" );}voidcenter(str, len, separate) const char *str; int len; int separate;{ char lineout[FMT_ST_CHARS]; center_str(str, lineout, SIZE(lineout), len); fputs(lineout, stdout); if (separate) (void)printf("%*s", separate, "");}voidusage(){ (void)fprintf(stderr, _("usage: cal [-13smjyV] [[month] year]\n")); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -