svn commit: r367207 - head/usr.bin/calendar
Stefan Eßer
se at FreeBSD.org
Sat Oct 31 15:11:24 UTC 2020
Author: se
Date: Sat Oct 31 15:11:24 2020
New Revision: 367207
URL: https://svnweb.freebsd.org/changeset/base/367207
Log:
Improve calendar file parsing and consistency tests
Add line number information to more warning and error messages.
Detect #else and #endif without corresponing #ifdef/#ifndef as error.
Detect missing #endif at end of file and print warning but continue.
Support for #undef has been added to reverse the effect of a prior #define.
It is no error if the argument value has not been defined before.
These changes may cause error aborts on malformed input files (e.g. with
spurious #else or #endif), but no such errors exist in the calendar files
in the FreeBSD base system and the calendar-data port and all tests pass.
More tests will be added in a follow-up commit to detect regressions that
might affect the newly added features.
This commit ends a series of updates that enhance the pre-processor and
make it behave much more like prior versions of the calendar progarm that
called cpp to pre-process the data files.
MFC after: 3 days
Relnotes: yes
Modified:
head/usr.bin/calendar/io.c
Modified: head/usr.bin/calendar/io.c
==============================================================================
--- head/usr.bin/calendar/io.c Sat Oct 31 14:59:39 2020 (r367206)
+++ head/usr.bin/calendar/io.c Sat Oct 31 15:11:24 2020 (r367207)
@@ -153,7 +153,7 @@ cal_fopen(const char *file)
warnx(format " in %s/%s/%s line %d", arg1, cal_home, cal_dir, cal_file, cal_line)
static int
-token(char *line, FILE *out, int *skip)
+token(char *line, FILE *out, int *skip, int *unskip)
{
char *walk, c, a;
const char *this_cal_home;
@@ -164,6 +164,13 @@ token(char *line, FILE *out, int *skip)
if (strncmp(line, "endif", 5) == 0) {
if (*skip > 0)
--*skip;
+ else if (*unskip > 0)
+ --*unskip;
+ else {
+ WARN0("#endif without prior #ifdef or #ifndef");
+ return (T_ERR);
+ }
+
return (T_OK);
}
@@ -178,7 +185,9 @@ token(char *line, FILE *out, int *skip)
if (*skip != 0 || definitions == NULL || sl_find(definitions, walk) == NULL)
++*skip;
-
+ else
+ ++*unskip;
+
return (T_OK);
}
@@ -193,6 +202,8 @@ token(char *line, FILE *out, int *skip)
if (*skip != 0 || (definitions != NULL && sl_find(definitions, walk) != NULL))
++*skip;
+ else
+ ++*unskip;
return (T_OK);
}
@@ -206,10 +217,18 @@ token(char *line, FILE *out, int *skip)
return (T_ERR);
}
- if (*skip == 0)
+ if (*unskip == 0) {
+ if (*skip == 0) {
+ WARN0("#else without prior #ifdef or #ifndef");
+ return (T_ERR);
+ } else if (*skip == 1) {
+ *skip = 0;
+ *unskip = 1;
+ }
+ } else if (*unskip == 1) {
*skip = 1;
- else if (*skip == 1)
- *skip = 0;
+ *unskip = 0;
+ }
return (T_OK);
}
@@ -267,10 +286,28 @@ token(char *line, FILE *out, int *skip)
return (T_ERR);
}
- sl_add(definitions, strdup(walk));
+ if (sl_find(definitions, walk) == NULL)
+ sl_add(definitions, strdup(walk));
return (T_OK);
}
+ if (strncmp(line, "undef", 5) == 0) {
+ if (definitions != NULL) {
+ walk = line + 5;
+ trimlr(&walk);
+
+ if (*walk == '\0') {
+ WARN0("Expecting arguments after #undef");
+ return (T_ERR);
+ }
+
+ walk = sl_find(definitions, walk);
+ if (walk != NULL)
+ walk[0] = '\0';
+ }
+ return (T_OK);
+ }
+
return (T_PROCESS);
}
@@ -299,6 +336,7 @@ cal_parse(FILE *in, FILE *out)
int day[MAXCOUNT];
int year[MAXCOUNT];
int skip = 0;
+ int unskip = 0;
char dbuf[80];
char *pp, p;
struct tm tm;
@@ -369,7 +407,7 @@ cal_parse(FILE *in, FILE *out)
continue;
if (buf == line && *buf == '#') {
- switch (token(buf+1, out, &skip)) {
+ switch (token(buf+1, out, &skip, &unskip)) {
case T_ERR:
free(line);
return (1);
@@ -448,8 +486,7 @@ cal_parse(FILE *in, FILE *out)
if (count < 0) {
/* Show error status based on return value */
if (debug)
- fprintf(stderr, "Ignored: \"%s\" in %s/%s/%s line %d\n",
- buf, cal_home, cal_dir, cal_file, cal_line);
+ WARN1("Ignored: \"%s\"", buf);
if (count == -1)
continue;
count = -count + 1;
@@ -469,12 +506,15 @@ cal_parse(FILE *in, FILE *out)
(void)strftime(dbuf, sizeof(dbuf),
d_first ? "%e %b" : "%b %e", &tm);
if (debug)
- fprintf(stderr, "got \"%s\" in %s/%s/%s line %d\n",
- pp, cal_home, cal_dir, cal_file, cal_line);
+ WARN1("got \"%s\"", pp);
events[i] = event_add(year[i], month[i], day[i], dbuf,
((flags &= F_VARIABLE) != 0) ? 1 : 0, pp,
extradata[i]);
}
+ }
+ while (skip-- > 0 || unskip-- > 0) {
+ cal_line++;
+ WARN0("Missing #endif assumed");
}
free(line);
More information about the svn-src-all
mailing list