Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 28 Oct 2020 14:48:59 +0000 (UTC)
From:      =?UTF-8?Q?Stefan_E=c3=9fer?= <se@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r367108 - head/usr.bin/calendar
Message-ID:  <202010281448.09SEmxG5002495@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: se
Date: Wed Oct 28 14:48:58 2020
New Revision: 367108
URL: https://svnweb.freebsd.org/changeset/base/367108

Log:
  Add support for nested conditionals
  
  The previous behavior was to support nested #ifdef and #ifndef, but to
  return to unconditional parsing after the next #endif, independently of
  the number of previously parsed conditions.
  
  E.g. after "#ifdef A / #ifdef B / #endif" the following lines were
  unconditially parsed again, independently of A and/or B being defined.
  
  The new behavior is to count the level of false conditions and to only
  restart parsing of calendar entries when the corresponding number of
  #endif tokens have been seen.
  
  In addition to the above, an #else directive has been added, to toggle
  between parsing and ignoring of the following lines.
  
  No validation of the correct use of the condition directives is made.
  #endif without prior #define or #ifndef is ignored and #else toggles
  between parsing and skipping of entries.
  
  The MFC period has been set to 1 month to allow for a review of the
  changes and for a discussion, whether these modifications should not
  be merged at all.
  
  No correct input file is parsed differently than before, but if calendar
  data files are published that use these new features, those data files
  will not parse correctly on prior versions of this program.
  
  MFC after:	1 month

Modified:
  head/usr.bin/calendar/calendar.1
  head/usr.bin/calendar/io.c

Modified: head/usr.bin/calendar/calendar.1
==============================================================================
--- head/usr.bin/calendar/calendar.1	Wed Oct 28 14:43:38 2020	(r367107)
+++ head/usr.bin/calendar/calendar.1	Wed Oct 28 14:48:58 2020	(r367108)
@@ -28,7 +28,7 @@
 .\"     @(#)calendar.1  8.1 (Berkeley) 6/29/93
 .\" $FreeBSD$
 .\"
-.Dd October 25, 2020
+.Dd October 28, 2020
 .Dt CALENDAR 1
 .Os
 .Sh NAME
@@ -198,7 +198,13 @@ file is preprocessed by a limited subset of
 .Xr cpp 1
 internally, allowing the inclusion of shared files such as
 lists of company holidays or meetings.
-This limited subset consists of \fB#include #ifndef #endif\fR and \fB#define\fR.
+This limited subset consists of \fB#include #ifdef #ifndef #else
+#endif\fR and \fB#define\fR. Conditions can be nested, but not check
+for matching begin and end directives is performed.
+Included files are parsed in their own scope.
+They have no read or write access to condition variables defined in
+an outer scope and open conditional blocks are implicitly closed.
+.Pp
 If the shared file is not referenced by a full pathname,
 .Nm
 searches in the current (or home) directory first, and then in the
@@ -346,9 +352,12 @@ double-check the start and end time of solar and lunar
 .Sh BUGS
 The
 .Nm
-internal cpp does not support nested conditions and will continue
-parsing of the input file on the next #endif even in nested contexts.
-It does only recognise #include, #define, #ifdef and #ifndef.
+does only recognise the cpp directives #include, #define, #ifdef,
+#ifndef and #else.
+It supports nested conditions, but does not perform any validation
+on the correct use and nesting of conditions.
+#endif without prior #ifdef or #define is ignored and #else outside
+a conditional section skips input lines up to the next #endif.
 .Pp
 There is no possibility to properly specify the local position
 needed for solar and lunar calculations.

Modified: head/usr.bin/calendar/io.c
==============================================================================
--- head/usr.bin/calendar/io.c	Wed Oct 28 14:43:38 2020	(r367107)
+++ head/usr.bin/calendar/io.c	Wed Oct 28 14:48:58 2020	(r367108)
@@ -140,18 +140,66 @@ cal_fopen(const char *file)
 }
 
 static int
-token(char *line, FILE *out, bool *skip)
+token(char *line, FILE *out, int *skip)
 {
 	char *walk, c, a;
 
 	if (strncmp(line, "endif", 5) == 0) {
-		*skip = false;
+		if (*skip > 0)
+			--*skip;
 		return (T_OK);
 	}
 
-	if (*skip)
+	if (strncmp(line, "ifdef", 5) == 0) {
+		walk = line + 5;
+		trimlr(&walk);
+
+		if (*walk == '\0') {
+			warnx("Expecting arguments after #ifdef");
+			return (T_ERR);
+		}
+
+		if (*skip != 0 || definitions == NULL || sl_find(definitions, walk) == NULL)
+			++*skip;
+
 		return (T_OK);
+	}
 
+	if (strncmp(line, "ifndef", 6) == 0) {
+		walk = line + 6;
+		trimlr(&walk);
+
+		if (*walk == '\0') {
+			warnx("Expecting arguments after #ifndef");
+			return (T_ERR);
+		}
+
+		if (*skip != 0 || (definitions != NULL && sl_find(definitions, walk) != NULL))
+			++*skip;
+
+		return (T_OK);
+	}
+
+	if (strncmp(line, "else", 4) == 0) {
+		walk = line + 4;
+		trimlr(&walk);
+
+		if (*walk != '\0') {
+			warnx("Expecting no arguments after #else");
+			return (T_ERR);
+		}
+
+		if (*skip == 0)
+			*skip = 1;
+		else if (*skip == 1)
+			*skip = 0;
+
+		return (T_OK);
+	}
+
+	if (*skip != 0)
+		return (T_OK);
+
 	if (strncmp(line, "include", 7) == 0) {
 		walk = line + 7;
 
@@ -212,36 +260,6 @@ token(char *line, FILE *out, bool *skip)
 		return (T_OK);
 	}
 
-	if (strncmp(line, "ifdef", 5) == 0) {
-		walk = line + 5;
-		trimlr(&walk);
-
-		if (*walk == '\0') {
-			warnx("Expecting arguments after #ifdef");
-			return (T_ERR);
-		}
-
-		if (definitions == NULL || sl_find(definitions, walk) == NULL)
-			*skip = true;
-
-		return (T_OK);
-	}
-
-	if (strncmp(line, "ifndef", 6) == 0) {
-		walk = line + 6;
-		trimlr(&walk);
-
-		if (*walk == '\0') {
-			warnx("Expecting arguments after #ifndef");
-			return (T_ERR);
-		}
-
-		if (definitions != NULL && sl_find(definitions, walk) != NULL)
-			*skip = true;
-
-		return (T_OK);
-	}
-
 	return (T_PROCESS);
 
 }
@@ -269,7 +287,7 @@ cal_parse(FILE *in, FILE *out)
 	int month[MAXCOUNT];
 	int day[MAXCOUNT];
 	int year[MAXCOUNT];
-	bool skip = false;
+	int skip = 0;
 	char dbuf[80];
 	char *pp, p;
 	struct tm tm;
@@ -299,7 +317,7 @@ cal_parse(FILE *in, FILE *out)
 			}
 		}
 
-		if (skip)
+		if (skip != 0)
 			continue;
 
 		buf = line;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202010281448.09SEmxG5002495>