Add regression tests for conditions and comments

Fix one case where #else was not corerctly processed and simplify the
conditions logic.

Fix parsing of day and month names in the locale specified in the calendar
file. The previous version would expect those names to match the locale of
the user.

Mention that comments are now correctly processed and that // is supported
in addition to /* ... */.

MFC after:	3 days
This commit is contained in:
Stefan Eßer 2020-11-04 22:29:01 +00:00
parent 07030f3362
commit 2ceb17a8be
14 changed files with 213 additions and 54 deletions

View File

@ -28,7 +28,7 @@
.\" @(#)calendar.1 8.1 (Berkeley) 6/29/93 .\" @(#)calendar.1 8.1 (Berkeley) 6/29/93
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd October 28, 2020 .Dd November 4, 2020
.Dt CALENDAR 1 .Dt CALENDAR 1
.Os .Os
.Sh NAME .Sh NAME
@ -218,12 +218,14 @@ If the shared file is not referenced by a full pathname,
searches in the current (or home) directory first, and then in the searches in the current (or home) directory first, and then in the
directory directory
.Pa /usr/share/calendar . .Pa /usr/share/calendar .
Empty lines and lines protected by the C commenting syntax Empty lines and text protected by the C commenting syntax
.Pq Li /* ... */ .Pq Li /* ... */
or
.Pq Li //
are ignored. are ignored.
.Pp .Pp
Some possible calendar entries (<tab> characters highlighted by Some possible calendar entries (<tab> characters highlighted by
\fB\et\fR sequence) \fB\et\fR sequence):
.Bd -unfilled -offset indent .Bd -unfilled -offset indent
LANG=C LANG=C
Easter=Ostern Easter=Ostern

View File

@ -122,7 +122,7 @@ extern int year1, year2;
* - Use event_continue() to add more text to the last added event * - Use event_continue() to add more text to the last added event
* - Use event_print_all() to display them in time chronological order * - Use event_print_all() to display them in time chronological order
*/ */
struct event *event_add(int, int, int, char *, int, char *, char *); struct event *event_add(int, int, int, int, char *, char *);
void event_continue(struct event *events, char *txt); void event_continue(struct event *events, char *txt);
void event_print_all(FILE *fp); void event_print_all(FILE *fp);
struct event { struct event {
@ -189,7 +189,7 @@ int remember_yd(int y, int d, int *rm, int *rd);
int first_dayofweek_of_year(int y); int first_dayofweek_of_year(int y);
int first_dayofweek_of_month(int y, int m); int first_dayofweek_of_month(int y, int m);
int walkthrough_dates(struct event **e); int walkthrough_dates(struct event **e);
void addtodate(struct event *e, int year, int month, int day); void addtodate(struct event *e);
/* pom.c */ /* pom.c */
#define MAXMOONS 18 #define MAXMOONS 18

View File

@ -444,12 +444,12 @@ find_day(int yy, int mm, int dd)
} }
void void
addtodate(struct event *e, int year, int month, int day) addtodate(struct event *e)
{ {
struct cal_day *d; struct cal_day *d;
struct event *ee; struct event *ee;
d = find_day(year, month, day); d = find_day(e->year, e->month, e->day);
ee = d->lastevent; ee = d->lastevent;
if (ee != NULL) if (ee != NULL)
ee->next = e; ee->next = e;

View File

@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <iconv.h> #include <iconv.h>
#include <errno.h> #include <errno.h>
#include <langinfo.h> #include <langinfo.h>
#include <locale.h>
static iconv_t conv = (iconv_t)-1; static iconv_t conv = (iconv_t)-1;
static char *currentEncoding = NULL; static char *currentEncoding = NULL;
@ -150,8 +151,7 @@ convert(char *input)
} }
struct event * struct event *
event_add(int year, int month, int day, char *date, int var, char *txt, event_add(int year, int month, int day, int var, char *txt, char *extra)
char *extra)
{ {
struct event *e; struct event *e;
@ -159,25 +159,22 @@ event_add(int year, int month, int day, char *date, int var, char *txt,
* Creating a new event: * Creating a new event:
* - Create a new event * - Create a new event
* - Copy the machine readable day and month * - Copy the machine readable day and month
* - Copy the human readable and language specific date
* - Copy the text of the event * - Copy the text of the event
*/ */
e = (struct event *)calloc(1, sizeof(struct event)); e = (struct event *)calloc(1, sizeof(struct event));
if (e == NULL) if (e == NULL)
errx(1, "event_add: cannot allocate memory"); errx(1, "event_add: cannot allocate memory");
e->year = year;
e->month = month; e->month = month;
e->day = day; e->day = day;
e->var = var; e->var = var;
e->date = convert(date);
if (e->date == NULL)
errx(1, "event_add: cannot allocate memory");
e->text = convert(txt); e->text = convert(txt);
if (e->text == NULL) if (e->text == NULL)
errx(1, "event_add: cannot allocate memory"); errx(1, "event_add: cannot allocate memory");
e->extra = NULL; e->extra = NULL;
if (extra != NULL && extra[0] != '\0') if (extra != NULL && extra[0] != '\0')
e->extra = convert(extra); e->extra = convert(extra);
addtodate(e, year, month, day); addtodate(e);
return (e); return (e);
} }
@ -204,20 +201,37 @@ void
event_print_all(FILE *fp) event_print_all(FILE *fp)
{ {
struct event *e; struct event *e;
struct tm tm;
char dbuf[80];
static int d_first;
const char *lang;
lang = getenv("LANG");
if (lang == NULL)
lang = "C";
if (setlocale(LC_ALL, lang) == NULL)
(void)setlocale(LC_ALL, "C");
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
while (walkthrough_dates(&e) != 0) { while (walkthrough_dates(&e) != 0) {
if (e) {
#ifdef DEBUG #ifdef DEBUG
if (e)
fprintf(stderr, "event_print_all month: %d, day: %d\n", fprintf(stderr, "event_print_all month: %d, day: %d\n",
e->month, e->day); e->month, e->day);
#endif #endif
memset(&tm, 0, sizeof(struct tm));
tm.tm_mday = e->day;
tm.tm_mon = e->month - 1;
tm.tm_year = e->year - 1900;
(void)strftime(dbuf, sizeof(dbuf), d_first ? "%e %b" : "%b %e", &tm);
}
/* /*
* Go through all events and print the text of the matching * Go through all events and print the text of the matching
* dates * dates
*/ */
while (e != NULL) { while (e != NULL) {
(void)fprintf(fp, "%s%c%s%s%s%s\n", e->date, (void)fprintf(fp, "%s%c%s%s%s%s\n", dbuf,
e->var ? '*' : ' ', e->text, e->var ? '*' : ' ', e->text,
e->extra != NULL ? " (" : "", e->extra != NULL ? " (" : "",
e->extra != NULL ? e->extra : "", e->extra != NULL ? e->extra : "",

View File

@ -50,7 +50,6 @@ __FBSDID("$FreeBSD$");
#include <ctype.h> #include <ctype.h>
#include <err.h> #include <err.h>
#include <errno.h> #include <errno.h>
#include <langinfo.h>
#include <locale.h> #include <locale.h>
#include <pwd.h> #include <pwd.h>
#include <stdbool.h> #include <stdbool.h>
@ -159,7 +158,9 @@ cal_path(void)
{ {
static char buffer[MAXPATHLEN + 10]; static char buffer[MAXPATHLEN + 10];
if (cal_dir[0] == '/') if (cal_dir == NULL)
snprintf(buffer, sizeof(buffer), "%s", cal_file);
else if (cal_dir[0] == '/')
snprintf(buffer, sizeof(buffer), "%s/%s", cal_dir, cal_file); snprintf(buffer, sizeof(buffer), "%s/%s", cal_dir, cal_file);
else else
snprintf(buffer, sizeof(buffer), "%s/%s/%s", cal_home, cal_dir, cal_file); snprintf(buffer, sizeof(buffer), "%s/%s/%s", cal_home, cal_dir, cal_file);
@ -181,14 +182,14 @@ token(char *line, FILE *out, int *skip, int *unskip)
int this_cal_line; int this_cal_line;
if (strncmp(line, "endif", 5) == 0) { if (strncmp(line, "endif", 5) == 0) {
if (*skip > 0) if (*skip + *unskip == 0) {
--*skip;
else if (*unskip > 0)
--*unskip;
else {
WARN0("#endif without prior #ifdef or #ifndef"); WARN0("#endif without prior #ifdef or #ifndef");
return (T_ERR); return (T_ERR);
} }
if (*skip > 0)
--*skip;
else
--*unskip;
return (T_OK); return (T_OK);
} }
@ -247,18 +248,17 @@ token(char *line, FILE *out, int *skip, int *unskip)
WARN0("Expecting no arguments after #else"); WARN0("Expecting no arguments after #else");
return (T_ERR); return (T_ERR);
} }
if (*skip + *unskip == 0) {
WARN0("#else without prior #ifdef or #ifndef");
return (T_ERR);
}
if (*unskip == 0) { if (*skip == 0) {
if (*skip == 0) { ++*skip;
WARN0("#else without prior #ifdef or #ifndef"); --*unskip;
return (T_ERR); } else if (*skip == 1) {
} else if (*skip == 1) { --*skip;
*skip = 0; ++*unskip;
*unskip = 1;
}
} else if (*unskip == 1) {
*skip = 1;
*unskip = 0;
} }
return (T_OK); return (T_OK);
@ -366,7 +366,6 @@ cal_parse(FILE *in, FILE *out)
size_t linecap = 0; size_t linecap = 0;
ssize_t linelen; ssize_t linelen;
ssize_t l; ssize_t l;
static int d_first = -1;
static int count = 0; static int count = 0;
int i; int i;
int month[MAXCOUNT]; int month[MAXCOUNT];
@ -374,19 +373,11 @@ cal_parse(FILE *in, FILE *out)
int year[MAXCOUNT]; int year[MAXCOUNT];
int skip = 0; int skip = 0;
int unskip = 0; int unskip = 0;
char dbuf[80];
char *pp, p; char *pp, p;
struct tm tm;
int flags; int flags;
char *c, *cc; char *c, *cc;
bool incomment = false; bool incomment = false;
/* Unused */
tm.tm_sec = 0;
tm.tm_min = 0;
tm.tm_hour = 0;
tm.tm_wday = 0;
if (in == NULL) if (in == NULL)
return (1); return (1);
@ -468,7 +459,7 @@ cal_parse(FILE *in, FILE *out)
* and does not run iconv(), this variable has little use. * and does not run iconv(), this variable has little use.
*/ */
if (strncmp(buf, "LANG=", 5) == 0) { if (strncmp(buf, "LANG=", 5) == 0) {
(void)setlocale(LC_CTYPE, buf + 5); (void)setlocale(LC_ALL, buf + 5);
#ifdef WITH_ICONV #ifdef WITH_ICONV
if (!doall) if (!doall)
set_new_encoding(); set_new_encoding();
@ -532,18 +523,10 @@ cal_parse(FILE *in, FILE *out)
while (pp[1] == '\t') while (pp[1] == '\t')
pp++; pp++;
if (d_first < 0)
d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
tm.tm_mon = month[i] - 1;
tm.tm_mday = day[i];
tm.tm_year = year[i] - 1900;
(void)strftime(dbuf, sizeof(dbuf),
d_first ? "%e %b" : "%b %e", &tm);
if (debug) if (debug)
WARN1("got \"%s\"", pp); WARN1("got \"%s\"", pp);
events[i] = event_add(year[i], month[i], day[i], dbuf, events[i] = event_add(year[i], month[i], day[i],
((flags &= F_VARIABLE) != 0) ? 1 : 0, pp, ((flags &= F_VARIABLE) != 0) ? 1 : 0, pp,
extradata[i]); extradata[i]);
} }
@ -592,6 +575,7 @@ opencalin(void)
FILE *fpin; FILE *fpin;
/* open up calendar file */ /* open up calendar file */
cal_file = calendarFile;
if ((fpin = fopen(calendarFile, "r")) == NULL) { if ((fpin = fopen(calendarFile, "r")) == NULL) {
if (doall) { if (doall) {
if (chdir(calendarHomes[0]) != 0) if (chdir(calendarHomes[0]) != 0)

View File

@ -2,10 +2,18 @@
PACKAGE= tests PACKAGE= tests
TAP_TESTS_SH= legacy_test TAP_TESTS_SH= comment_test cond_test legacy_test
TEST_METADATA.comment_test+= timeout="600"
TEST_METADATA.cond_test+= timeout="600"
TEST_METADATA.legacy_test+= timeout="600" TEST_METADATA.legacy_test+= timeout="600"
${PACKAGE}FILES+= calendar.comment
${PACKAGE}FILES+= regress.comment.out
${PACKAGE}FILES+= calendar.cond
${PACKAGE}FILES+= regress.cond.out
${PACKAGE}FILES+= calendar.calibrate ${PACKAGE}FILES+= calendar.calibrate
${PACKAGE}FILES+= regress.a1.out ${PACKAGE}FILES+= regress.a1.out
${PACKAGE}FILES+= regress.a2.out ${PACKAGE}FILES+= regress.a2.out

View File

@ -0,0 +1,10 @@
1 1 jan 1 // comment
1 2 jan 2 /* comment */
1 3 jan /* comment */3
1 4 /* comment*/jan 4
// comment
/* comment */1 5 jan 5
1/* comment */ 6 jan 6
1 7 jan 7 // /* comment */ comment
1 1/* comment */1 jan /* comment */11 // comment

View File

@ -0,0 +1,83 @@
#define DEF1
1 1 jan 1 OK
#ifdef DEF1
1 2 jan 2 OK
#endif
1 3 jan 3 OK
#ifdef DEF2
1 4 jan 4 NOT OK
#else
1 5 jan 5 OK
#endif
#ifndef DEF2
1 6 jan 6 OK
#else
1 7 jan 7 NOT OK
#endif
#ifdef DEF1
#ifndef DEF2
1 8 jan 8 OK
#endif
#endif
#ifdef DEF1
#ifdef DEF2
1 9 jan 9 NOT OK
#else
1 10 jan 10 OK
#endif
#else
1 11 jan 11 NOT OK
#endif
#define DEF2
#ifndef DEF1 // skip = 1
#ifndef DEF2 // skip = 2
1 12 jan 12 NOT OK
#else // skip = 1 unskip = 0
1 13 jan 13 NOT OK
#endif // skip = 0 unskip = 0
#else // skip = 0 unskip = 1
1 14 jan 14 OK
#endif // skip = 0 unskip = 0
#undef DEF1
#ifdef DEF1 // OFF
#ifdef DEF2 // ON
#ifdef DEF3 // OFF
1 15 jan 15 NOT OK
#else
1 16 jan 16 NOT OK
#endif // DEF3
#else // DEF2
#ifdef DEF3
1 17 jan 17 NOT OK
#else
1 18 jan 18 NOT OK
#endif // DEF3
#endif // DEF2
#else // DEF1
#ifdef DEF2
#ifdef DEF3
1 19 jan 19 NOT OK
#else
1 20 jan 20 OK
#endif // DEF3
#else // DEF2
#ifdef DEF3
1 21 jan 21 NOT OK
#else
1 22 jan 22 NOT OK
#endif // DEF3
#endif // DEF2
#endif // DEF1
1 23 jan 23 OK

View File

@ -0,0 +1,14 @@
# $FreeBSD$
CALENDAR_FILE="-f ${SRCDIR}/calendar.comment"
CALENDAR_BIN="calendar"
CALENDAR="${CALENDAR_BIN} ${CALENDAR_FILE}"
REGRESSION_START($1)
echo 1..1
REGRESSION_TEST(`comment',`$CALENDAR -t 01.01.2020 -A 30')
REGRESSION_END()

View File

@ -0,0 +1,6 @@
#!/bin/sh
# $FreeBSD$
SRCDIR="$(dirname "${0}")"; export SRCDIR
m4 "${SRCDIR}/../regress.m4" "${SRCDIR}/comment.sh" | sh

14
usr.bin/calendar/tests/cond.sh Executable file
View File

@ -0,0 +1,14 @@
# $FreeBSD$
CALENDAR_FILE="-f ${SRCDIR}/calendar.cond"
CALENDAR_BIN="calendar"
CALENDAR="${CALENDAR_BIN} ${CALENDAR_FILE}"
REGRESSION_START($1)
echo 1..1
REGRESSION_TEST(`cond',`$CALENDAR -t 01.01.2020 -A 30')
REGRESSION_END()

View File

@ -0,0 +1,6 @@
#!/bin/sh
# $FreeBSD$
SRCDIR="$(dirname "${0}")"; export SRCDIR
m4 "${SRCDIR}/../regress.m4" "${SRCDIR}/cond.sh" | sh

View File

@ -0,0 +1,8 @@
Jan 1 jan 1
Jan 2 jan 2
Jan 3 jan 3
Jan 4 jan 4
Jan 5 jan 5
Jan 6 jan 6
Jan 7 jan 7
Jan 11 jan 11

View File

@ -0,0 +1,10 @@
Jan 1 jan 1 OK
Jan 2 jan 2 OK
Jan 3 jan 3 OK
Jan 5 jan 5 OK
Jan 6 jan 6 OK
Jan 8 jan 8 OK
Jan 10 jan 10 OK
Jan 14 jan 14 OK
Jan 20 jan 20 OK
Jan 23 jan 23 OK