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
This commit is contained in:
parent
6688708624
commit
8e8c5da47f
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user