int main(int argc, char *argv[]) { struct tm *local_time; time_t now; int ch, month, year, yflag; const char *errstr; yflag = year = 0; while ((ch = getopt(argc, argv, "jmwy")) != -1) switch(ch) { case 'j': julian = 1; break; case 'm': mflag = 1; break; case 'w': wflag = 1; break; case 'y': yflag = 1; break; case '?': default: usage(); } argc -= optind; argv += optind; if (julian && wflag) usage(); day_headings = DAY_HEADINGS_S; sep1752 = sep1752s; if (mflag && julian) { sep1752 = sep1752jm; day_headings = DAY_HEADINGS_JM; } else if (mflag) { sep1752 = sep1752m; day_headings = DAY_HEADINGS_M; } else if (julian) { sep1752 = sep1752js; day_headings = DAY_HEADINGS_JS; } month = 0; switch(argc) { case 2: month = parsemonth(*argv++); if (!month) errx(1, "Unable to parse month"); /* FALLTHROUGH */ case 1: if (argc == 1 && !isdigit((unsigned char)*argv[0])) { month = parsemonth(*argv); if (!month) errx(1, "illegal year value: use 1-9999"); (void)time(&now); local_time = localtime(&now); year = local_time->tm_year + TM_YEAR_BASE; } else { year = strtonum(*argv, 1, 9999, &errstr); if (errstr) errx(1, "illegal year value: use 1-9999"); } break; case 0: (void)time(&now); local_time = localtime(&now); year = local_time->tm_year + TM_YEAR_BASE; if (!yflag) month = local_time->tm_mon + 1; break; default: usage(); } if (month) monthly(month, year); else if (julian) j_yearly(year); else yearly(year); exit(0); }
int main(int argc, char *argv[]) { struct djswitch *p, *q; /* to search user defined switch date */ date never = {10000, 1, 1}; /* outside valid range of dates */ date ukswitch = {1752, 9, 2};/* switch date for Great Britain */ date dt; int ch; /* holds the option character */ int m = 0; /* month */ int y = 0; /* year */ int flag_backward = 0; /* user called cal--backward compat. */ int flag_wholeyear = 0; /* user wants the whole year */ int flag_julian_cal = 0; /* user wants Julian Calendar */ int flag_julian_day = 0; /* user wants the Julian day numbers */ int flag_orthodox = 0; /* user wants Orthodox easter */ int flag_easter = 0; /* user wants easter date */ int flag_3months = 0; /* user wants 3 month display (-3) */ int flag_after = 0; /* user wants to see months after */ int flag_before = 0; /* user wants to see months before */ int flag_specifiedmonth = 0;/* user wants to see this month (-m) */ int flag_givenmonth = 0; /* user has specified month [n] */ int flag_givenyear = 0; /* user has specified year [n] */ char *cp; /* character pointer */ char *flag_today = NULL; /* debug: use date as being today */ char *flag_month = NULL; /* requested month as string */ char *flag_highlightdate = NULL; /* debug: date to highlight */ int before, after; const char *locale; /* locale to get country code */ flag_nohighlight = 0; flag_weeks = 0; /* * Use locale to determine the country code, * and use the country code to determine the default * switchdate and date format from the switches table. */ if (setlocale(LC_ALL, "") == NULL) warn("setlocale"); locale = setlocale(LC_TIME, NULL); if (locale == NULL || strcmp(locale, "C") == 0 || strcmp(locale, "POSIX") == 0 || strcmp(locale, "ASCII") == 0 || strcmp(locale, "US-ASCII") == 0) locale = "_US"; q = switches + sizeof(switches) / sizeof(struct djswitch); for (p = switches; p != q; p++) if ((cp = strstr(locale, p->cc)) != NULL && *(cp - 1) == '_') break; if (p == q) { nswitch = ndaysj(&dftswitch->dt); } else { nswitch = ndaysj(&p->dt); dftswitch = p; } /* * Get the filename portion of argv[0] and set flag_backward if * this program is called "cal". */ if (strncmp(basename(argv[0]), "cal", strlen("cal")) == 0) flag_backward = 1; /* Set the switch date to United Kingdom if backwards compatible */ if (flag_backward) nswitchb = ndaysj(&ukswitch); before = after = -1; while ((ch = getopt(argc, argv, "3A:B:Cd:eH:hjJm:Nops:wy")) != -1) switch (ch) { case '3': flag_3months = 1; break; case 'A': if (flag_after > 0) errx(EX_USAGE, "Double -A specified"); flag_after = strtol(optarg, NULL, 10); if (flag_after <= 0) errx(EX_USAGE, "Argument to -A must be positive"); break; case 'B': if (flag_before > 0) errx(EX_USAGE, "Double -A specified"); flag_before = strtol(optarg, NULL, 10); if (flag_before <= 0) errx(EX_USAGE, "Argument to -B must be positive"); break; case 'J': if (flag_backward) usage(); nswitch = ndaysj(&never); flag_julian_cal = 1; break; case 'C': flag_backward = 1; break; case 'N': flag_backward = 0; break; case 'd': flag_today = optarg; break; case 'H': flag_highlightdate = optarg; break; case 'h': flag_nohighlight = 1; break; case 'e': if (flag_backward) usage(); flag_easter = 1; break; case 'j': flag_julian_day = 1; break; case 'm': if (flag_specifiedmonth) errx(EX_USAGE, "Double -m specified"); flag_month = optarg; flag_specifiedmonth = 1; break; case 'o': if (flag_backward) usage(); flag_orthodox = 1; flag_easter = 1; break; case 'p': if (flag_backward) usage(); printcc(); return (0); break; case 's': if (flag_backward) usage(); q = switches + sizeof(switches) / sizeof(struct djswitch); for (p = switches; p != q && strcmp(p->cc, optarg) != 0; p++) ; if (p == q) errx(EX_USAGE, "%s: invalid country code", optarg); nswitch = ndaysj(&(p->dt)); break; case 'w': if (flag_backward) usage(); flag_weeks = 1; break; case 'y': flag_wholeyear = 1; break; default: usage(); } argc -= optind; argv += optind; switch (argc) { case 2: if (flag_easter) usage(); flag_month = *argv++; flag_givenmonth = 1; m = strtol(flag_month, NULL, 10); /* FALLTHROUGH */ case 1: y = atoi(*argv); if (y < 1 || y > 9999) errx(EX_USAGE, "year `%s' not in range 1..9999", *argv); argv++; flag_givenyear = 1; break; case 0: if (flag_today != NULL) { y = strtol(flag_today, NULL, 10); m = strtol(flag_today + 5, NULL, 10); } else { time_t t; struct tm *tm; t = time(NULL); tm = localtime(&t); y = tm->tm_year + 1900; m = tm->tm_mon + 1; } break; default: usage(); } if (flag_month != NULL) { if (parsemonth(flag_month, &m, &y)) { errx(EX_USAGE, "%s is neither a month number (1..12) nor a name", flag_month); } } /* * What is not supported: * -3 with -A or -B * -3 displays 3 months, -A and -B change that behaviour. * -3 with -y * -3 displays 3 months, -y says display a whole year. * -3 with a given year but no given month or without -m * -3 displays 3 months, no month specified doesn't make clear * which three months. * -m with a given month * conflicting arguments, both specify the same field. * -y with -m * -y displays the whole year, -m displays a single month. * -y with a given month * -y displays the whole year, the given month displays a single * month. * -y with -A or -B * -y displays the whole year, -A and -B display extra months. */ /* -3 together with -A or -B. */ if (flag_3months && (flag_after || flag_before)) errx(EX_USAGE, "-3 together with -A and -B is not supported."); /* -3 together with -y. */ if (flag_3months && flag_wholeyear) errx(EX_USAGE, "-3 together with -y is not supported."); /* -3 together with givenyear but no givenmonth. */ if (flag_3months && flag_givenyear && !(flag_givenmonth || flag_specifiedmonth)) errx(EX_USAGE, "-3 together with a given year but no given month is " "not supported."); /* -m together with xx xxxx. */ if (flag_specifiedmonth && flag_givenmonth) errx(EX_USAGE, "-m together with a given month is not supported."); /* -y together with -m. */ if (flag_wholeyear && flag_specifiedmonth) errx(EX_USAGE, "-y together with -m is not supported."); /* -y together with xx xxxx. */ if (flag_wholeyear && flag_givenmonth) errx(EX_USAGE, "-y together a given month is not supported."); /* -y together with -A or -B. */ if (flag_wholeyear && (flag_before > 0 || flag_after > 0)) errx(EX_USAGE, "-y together a -A or -B is not supported."); /* The rest should be fine. */ /* Select the period to display, in order of increasing priority .*/ if (flag_wholeyear || (flag_givenyear && !(flag_givenmonth || flag_specifiedmonth))) { m = 1; before = 0; after = 11; } if (flag_givenyear && flag_givenmonth) { before = 0; after = 0; } if (flag_specifiedmonth) { before = 0; after = 0; } if (flag_before) { before = flag_before; } if (flag_after) { after = flag_after; } if (flag_3months) { before = 1; after = 1; } if (after == -1) after = 0; if (before == -1) before = 0; /* Highlight a specified day or today .*/ if (flag_highlightdate != NULL) { dt.y = strtol(flag_highlightdate, NULL, 10); dt.m = strtol(flag_highlightdate + 5, NULL, 10); dt.d = strtol(flag_highlightdate + 8, NULL, 10); } else { time_t t; struct tm *tm1; t = time(NULL); tm1 = localtime(&t); dt.y = tm1->tm_year + 1900; dt.m = tm1->tm_mon + 1; dt.d = tm1->tm_mday; } highlightdate = sndaysb(&dt); /* And now we finally start to calculate and output calendars. */ if (flag_easter) printeaster(y, flag_julian_cal, flag_orthodox); else if (flag_backward) monthrangeb(y, m, flag_julian_day, before, after); else monthranger(y, m, flag_julian_day, before, after); return (0); }