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); _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"