Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.bin/cal - add -A and -B option.



details:   https://anonhg.NetBSD.org/src/rev/ba83dc927e3c
branches:  trunk
changeset: 538683:ba83dc927e3c
user:      yamt <yamt%NetBSD.org@localhost>
date:      Fri Oct 25 20:06:56 2002 +0000

description:
- add -A and -B option.
- change -3 to a synonym of "-A1 -B1".
  (to make compatible other implementations)
- eliminate duplicated codes.
- fix crashes for -3.

diffstat:

 usr.bin/cal/cal.1 |   19 ++-
 usr.bin/cal/cal.c |  307 +++++++++++++++++++++++++++++------------------------
 2 files changed, 180 insertions(+), 146 deletions(-)

diffs (truncated from 455 to 300 lines):

diff -r cb417945d54c -r ba83dc927e3c usr.bin/cal/cal.1
--- a/usr.bin/cal/cal.1 Fri Oct 25 18:57:06 2002 +0000
+++ b/usr.bin/cal/cal.1 Fri Oct 25 20:06:56 2002 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: cal.1,v 1.11 2002/06/23 00:22:56 wiz Exp $
+.\"    $NetBSD: cal.1,v 1.12 2002/10/25 20:06:56 yamt Exp $
 .\"
 .\" Copyright (c) 1989, 1990, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -36,7 +36,7 @@
 .\"
 .\"     @(#)cal.1      8.2 (Berkeley) 4/28/95
 .\"
-.Dd April 28, 1995
+.Dd October 25, 2002
 .Dt CAL 1
 .Os
 .Sh NAME
@@ -45,6 +45,8 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl jy3
+.Op Fl A after
+.Op Fl B before
 .Op Oo Ar month Oc Ar \ year
 .Sh DESCRIPTION
 .Nm
@@ -53,15 +55,20 @@
 the current month is displayed.
 The options are as follows:
 .Bl -tag -width Ds
+.It Fl A Ar after
+Display
+.Ar after
+monthes after the specified month.
+.It Fl B Ar before 
+Display
+.Ar before
+monthes before the specified month.
 .It Fl j
 Display julian dates (days one-based, numbered from January 1).
 .It Fl y
 Display a calendar for the current year.
 .It Fl 3
-Display a three month calendar, starting with the current month or the
-specified year and month. If a year is specified but no month is
-specified January is assumed. This option is not compatible with
-.Fl j .
+Same as -A1 -B1.
 .El
 .Pp
 A single parameter specifies the year (1 - 9999) to be displayed;
diff -r cb417945d54c -r ba83dc927e3c usr.bin/cal/cal.c
--- a/usr.bin/cal/cal.c Fri Oct 25 18:57:06 2002 +0000
+++ b/usr.bin/cal/cal.c Fri Oct 25 20:06:56 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cal.c,v 1.13 2002/06/22 21:14:18 perry Exp $   */
+/*     $NetBSD: cal.c,v 1.14 2002/10/25 20:06:56 yamt Exp $    */
 
 /*
  * Copyright (c) 1989, 1993, 1994
@@ -46,7 +46,7 @@
 #if 0
 static char sccsid[] = "@(#)cal.c      8.4 (Berkeley) 4/2/94";
 #else
-__RCSID("$NetBSD: cal.c,v 1.13 2002/06/22 21:14:18 perry Exp $");
+__RCSID("$NetBSD: cal.c,v 1.14 2002/10/25 20:06:56 yamt Exp $");
 #endif
 #endif /* not lint */
 
@@ -54,6 +54,8 @@
 
 #include <ctype.h>
 #include <err.h>
+#include <errno.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -125,30 +127,36 @@
 
 int julian;
 
+int    getnum(const char *);
 void   ascii_day(char *, int);
 void   center(char *, int, int);
 void   day_array(int, int, int *);
 int    day_in_week(int, int, int);
 int    day_in_year(int, int, int);
-void   j_yearly(int);
-void   month3(int, int);
-void   monthly(int, int);
+void   monthrange(int, int, int, int, int);
 int    main(int, char **);
 void   trim_trailing_spaces(char *);
 void   usage(void);
-void   yearly(int);
 
 int
 main(int argc, char **argv)
 {
        struct tm *local_time;
        time_t now;
-       int ch, month, year, yflag, threeflag;
+       int ch, month, year, yflag;
+       int before, after;
+       int yearly = 0;
 
+       before = after = 0;
        yflag = year = 0;
-       threeflag = 0;
-       while ((ch = getopt(argc, argv, "jy3")) != -1) {
+       while ((ch = getopt(argc, argv, "A:B:jy3")) != -1) {
                switch (ch) {
+               case 'A':
+                       after = getnum(optarg);
+                       break;
+               case 'B':
+                       before = getnum(optarg);
+                       break;
                case 'j':
                        julian = 1;
                        break;
@@ -156,7 +164,7 @@
                        yflag = 1;
                        break;
                case '3':
-                       threeflag = 1;
+                       before = after = 1;
                        break;
                case '?':
                default:
@@ -165,10 +173,6 @@
                }
        }
 
-       if (threeflag && julian) {
-               usage();
-       }
-
        argc -= optind;
        argv += optind;
 
@@ -193,14 +197,15 @@
                usage();
        }
 
-       if (threeflag)
-               month3(month ? month : 1 , year);
-       else if (month)
-               monthly(month, year);
-       else if (julian)
-               j_yearly(year);
-       else
-               yearly(year);
+       if (!month) {
+               /* yearly */
+               month = 1;
+               before = 0;
+               after = 11;
+               yearly = 1;
+       }
+
+       monthrange(month, year, before, after, yearly);
 
        exit(0);
 }
@@ -211,136 +216,135 @@
 #define        J_WEEK_LEN      27              /* 7 * 4 - one space at the end */
 #define        HEAD_SEP        2               /* spaces between day headings */
 #define        J_HEAD_SEP      2
-
-void
-monthly(int month, int year)
-{
-       int col, row, len, days[MAXDAYS];
-       char *p, lineout[30];
-
-       day_array(month, year, days);
-       len = snprintf(lineout, sizeof(lineout), "%s %d",
-           month_names[month - 1], year);
-       (void)printf("%*s%s\n%s\n",
-           ((julian ? J_WEEK_LEN : WEEK_LEN) - len) / 2, "",
-           lineout, julian ? j_day_headings : day_headings);
-       for (row = 0; row < 6; row++) {
-               for (col = 0, p = lineout; col < 7; col++,
-                   p += julian ? J_DAY_LEN : DAY_LEN)
-                       ascii_day(p, days[row * 7 + col]);
-               *p = '\0';
-               trim_trailing_spaces(lineout);
-               (void)printf("%s\n", lineout);
-       }
-}
+#define        MONTH_PER_ROW   3               /* how many monthes in a row */
+#define        J_MONTH_PER_ROW 2
 
 void
-j_yearly(int year)
+monthrange(int month, int year, int before, int after, int yearly)
 {
-       int col, *dp, i, month, row, which_cal;
-       int days[12][MAXDAYS];
-       char *p, lineout[80];
+       int startmonth, startyear;
+       int endmonth, endyear;
+       int i, row;
+       int days[3][MAXDAYS];
+       char lineout[80];
+       int inayear;
+       int newyear;
+       int day_len, week_len, head_sep;
+       int month_per_row;
+       int skip;
+
+       if (julian) {
+               day_len = J_DAY_LEN;
+               week_len = J_WEEK_LEN;
+               head_sep = J_HEAD_SEP;
+               month_per_row = J_MONTH_PER_ROW;
+       }
+       else {
+               day_len = DAY_LEN;
+               week_len = WEEK_LEN;
+               head_sep = HEAD_SEP;
+               month_per_row = MONTH_PER_ROW;
+       }
+
+       month--;
+
+       startyear = year - (before + 12 - 1 - month) / 12;
+       startmonth = 12 - 1 - ((before + 12 - 1 - month) % 12);
+       endyear = year + (month + after) / 12;
+       endmonth = (month + after) % 12;
+
+       if (startyear < 0 || endyear > 9999) {
+               errx(1, "year should be in 1-9999\n");
+       }
+
+       year = startyear;
+       month = startmonth;
+       inayear = newyear = (year != endyear || yearly);
+       if (inayear) {
+               skip = month % month_per_row;
+               month -= skip;
+       }
+       else {
+               skip = 0;
+       }
 
-       (void)snprintf(lineout, sizeof(lineout), "%d", year);
-       center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0);
-       (void)printf("\n\n");
-       for (i = 0; i < 12; i++)
-               day_array(i + 1, year, days[i]);
-       (void)memset(lineout, ' ', sizeof(lineout) - 1);
-       lineout[sizeof(lineout) - 1] = '\0';
-       for (month = 0; month < 12; month += 2) {
-               center(month_names[month], J_WEEK_LEN, J_HEAD_SEP);
-               center(month_names[month + 1], J_WEEK_LEN, 0);
-               (void)printf("\n%s%*s%s\n", j_day_headings, J_HEAD_SEP, "",
-                   j_day_headings);
+       do {
+               if (newyear) {
+                       (void)snprintf(lineout, sizeof(lineout), "%d", year);
+                       center(lineout, week_len * month_per_row +
+                           head_sep * (month_per_row - 1), 0);
+                       (void)printf("\n\n");
+                       newyear = 0;
+               }
+
+               for (i = 0; i < skip; i++)
+                       center("", week_len, head_sep);
+
+               for (; i < month_per_row; i++) {
+                       int sep;
+
+                       if (year == endyear && month + i > endmonth)
+                               break;
+
+                       sep = (i == month_per_row - 1) ? 0 : head_sep;
+                       day_array(month + i + 1, year, days[i]);
+                       if (inayear) {
+                               center(month_names[month + i], week_len, sep);
+                       }
+                       else {
+                               snprintf(lineout, sizeof(lineout), "%s %d",
+                                   month_names[month + i], year);
+                               center(lineout, week_len, sep);
+                       }
+               }
+               printf("\n");
+
+               for (i = 0; i < skip; i++)
+                       center("", week_len, head_sep);
+
+               for (; i < month_per_row; i++) {
+                       int sep;
+
+                       if (year == endyear && month + i > endmonth)
+                               break;



Home | Main Index | Thread Index | Old Index