diff options
author | Stefan Eßer <se@FreeBSD.org> | 2020-10-31 15:11:24 +0000 |
---|---|---|
committer | Stefan Eßer <se@FreeBSD.org> | 2020-10-31 15:11:24 +0000 |
commit | 8e8c5da47fdbe10ea37cdc999f88a6b4b8714147 (patch) | |
tree | 12f1a2beb50841250dd284c0a76d55a4ec216f6a /usr.bin | |
parent | 6688708624f1298d9b2f86a780d8a69d0b3d0058 (diff) | |
download | src-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.c | 62 |
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); |