summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorStefan Eßer <se@FreeBSD.org>2020-10-31 15:11:24 +0000
committerStefan Eßer <se@FreeBSD.org>2020-10-31 15:11:24 +0000
commit8e8c5da47fdbe10ea37cdc999f88a6b4b8714147 (patch)
tree12f1a2beb50841250dd284c0a76d55a4ec216f6a /usr.bin
parent6688708624f1298d9b2f86a780d8a69d0b3d0058 (diff)
downloadsrc-test-8e8c5da47fdbe10ea37cdc999f88a6b4b8714147.tar.gz
src-test-8e8c5da47fdbe10ea37cdc999f88a6b4b8714147.zip
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
Notes
Notes: svn path=/head/; revision=367207
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/calendar/io.c62
1 files changed, 51 insertions, 11 deletions
diff --git a/usr.bin/calendar/io.c b/usr.bin/calendar/io.c
index 8de8ebf871451..41037cfc2d5b5 100644
--- a/usr.bin/calendar/io.c
+++ b/usr.bin/calendar/io.c
@@ -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,7 +286,25 @@ 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);
}
@@ -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,13 +506,16 @@ 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);
fclose(in);