Re-implement comment parsing missing in the internal pre-processor

The internal pre-processor ignored lines that did not parse a calendar
entries, but did not support multi-line comments in the way the external
cpp did.

The calendar files distributed with the base system (now in a port) do
use comments, though.

Implement comment processing for single-line (//) and multi-line comments
(/* */) with same semantics as in a standard C pre-processor.

All tests pass with this version, but there are no tests that specifically
verify comment processing.

Reported by:	jhs@berklix.com (Julian H. Stacey)
MFC after:	3 days
This commit is contained in:
Stefan Eßer 2020-10-30 10:44:46 +00:00
parent 86e149e16e
commit 0f352f4e25
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=367161

View File

@ -278,6 +278,8 @@ cal_parse(FILE *in, FILE *out)
char *pp, p;
struct tm tm;
int flags;
char *c, *cc;
bool incomment = false;
/* Unused */
tm.tm_sec = 0;
@ -289,8 +291,55 @@ cal_parse(FILE *in, FILE *out)
return (1);
while ((linelen = getline(&line, &linecap, in)) > 0) {
if (*line == '#') {
switch (token(line+1, out, &skip)) {
buf = line;
if (buf[linelen - 1] == '\n')
buf[--linelen] = '\0';
if (incomment) {
c = strstr(buf, "*/");
if (c) {
c += 2;
linelen -= c - buf;
buf = c;
incomment = false;
} else {
continue;
}
}
if (!incomment) {
do {
c = strstr(buf, "//");
cc = strstr(buf, "/*");
if (c != NULL && (cc == NULL || c - cc < 0)) {
*c = '\0';
linelen = c - buf;
break;
} else if (cc != NULL) {
c = strstr(cc + 2, "*/");
if (c != NULL) {
c += 2;
memmove(cc, c, c - buf + linelen);
linelen -= c - cc;
} else {
*cc = '\0';
linelen = cc - buf;
incomment = true;
break;
}
}
} while (c != NULL || cc != NULL);
}
for (l = linelen;
l > 0 && isspace((unsigned char)buf[l - 1]);
l--)
;
buf[l] = '\0';
if (buf[0] == '\0')
continue;
if (buf == line && *buf == '#') {
switch (token(buf+1, out, &skip)) {
case T_ERR:
free(line);
return (1);
@ -306,15 +355,6 @@ cal_parse(FILE *in, FILE *out)
if (skip != 0)
continue;
buf = line;
for (l = linelen;
l > 0 && isspace((unsigned char)buf[l - 1]);
l--)
;
buf[l] = '\0';
if (buf[0] == '\0')
continue;
/*
* Setting LANG in user's calendar was an old workaround
* for 'calendar -a' being run with C locale to properly