svn commit: r367364 - head/usr.bin/calendar

Stefan Eßer se at FreeBSD.org
Thu Nov 5 08:58:22 UTC 2020


Author: se
Date: Thu Nov  5 08:58:21 2020
New Revision: 367364
URL: https://svnweb.freebsd.org/changeset/base/367364

Log:
  Restrict locale settings to the file they occur in
  
  This prevents LANG= in an included file from affecting the interpretation
  of month and day names in the including file.
  
  Make the internal pre-processor accept white space between the "#" at
  the start of the line and the keyword for better compatibility with cpp.
  
  Add support for the cpp keywords #warning and #error.
  
  MFC after:	3 days

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

Modified: head/usr.bin/calendar/calendar.1
==============================================================================
--- head/usr.bin/calendar/calendar.1	Thu Nov  5 07:59:05 2020	(r367363)
+++ head/usr.bin/calendar/calendar.1	Thu Nov  5 08:58:21 2020	(r367364)
@@ -28,7 +28,7 @@
 .\"     @(#)calendar.1  8.1 (Berkeley) 6/29/93
 .\" $FreeBSD$
 .\"
-.Dd November 4, 2020
+.Dd November 5, 2020
 .Dt CALENDAR 1
 .Os
 .Sh NAME
@@ -199,13 +199,14 @@ file is preprocessed by a limited subset of
 internally, allowing the inclusion of shared files such as
 lists of company holidays or meetings.
 This limited subset consists of \fB#include\fR, \fB#define\fR,
-\fB#undef\fR, \fB#ifdef\fR, \fB#ifndef\fR, and \fB#else\fR.
+\fB#undef\fR, \fB#ifdef\fR, \fB#ifndef\fR, \fB#else\fR, \fB#warning\fR,
+and \fB#error\fR.
 .Pp
 Conditions can be nested and the consistency of opening and closing
 instructions is checked.
 Only the first word after #define is used as the name of the
 condition variable being defined.
-More than word following #ifdef, #ifndef, or #undef is a ayntax
+More than word following #ifdef, #ifndef, or #undef is considered a syntax
 error, since names cannot include white-space.
 Included files are parsed in a global scope with regard to the condition
 variables being defined or tested therein.

Modified: head/usr.bin/calendar/calendar.h
==============================================================================
--- head/usr.bin/calendar/calendar.h	Thu Nov  5 07:59:05 2020	(r367363)
+++ head/usr.bin/calendar/calendar.h	Thu Nov  5 08:58:21 2020	(r367364)
@@ -130,7 +130,6 @@ struct event {
 	int	month;
 	int	day;
 	int	var;
-	char	*date;
 	char	*text;
 	char	*extra;
 	struct event *next;

Modified: head/usr.bin/calendar/events.c
==============================================================================
--- head/usr.bin/calendar/events.c	Thu Nov  5 07:59:05 2020	(r367363)
+++ head/usr.bin/calendar/events.c	Thu Nov  5 08:58:21 2020	(r367364)
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
 #include <iconv.h>
 #include <errno.h>
 #include <langinfo.h>
-#include <locale.h>
 
 static iconv_t conv = (iconv_t)-1;
 static char *currentEncoding = NULL;
@@ -204,13 +203,7 @@ event_print_all(FILE *fp)
 	struct tm tm;
 	char dbuf[80];
 	static int d_first;
-	const char *lang;
 
-	lang = getenv("LANG");
-	if (lang == NULL)
-		lang = "C";
-	if (setlocale(LC_ALL, lang) == NULL)
-		(void)setlocale(LC_ALL, "C");
 	d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
 
 	while (walkthrough_dates(&e) != 0) {

Modified: head/usr.bin/calendar/io.c
==============================================================================
--- head/usr.bin/calendar/io.c	Thu Nov  5 07:59:05 2020	(r367363)
+++ head/usr.bin/calendar/io.c	Thu Nov  5 08:58:21 2020	(r367364)
@@ -172,6 +172,16 @@ cal_path(void)
 #define	WARN1(format, arg1)		   \
 	warnx(format " in %s line %d", arg1, cal_path(), cal_line)
 
+static char*
+cmptoken(char *line, const char* token)
+{
+	char len = strlen(token);
+
+	if (strncmp(line, token, len) != 0)
+		return NULL;
+	return (line + len);
+}
+
 static int
 token(char *line, FILE *out, int *skip, int *unskip)
 {
@@ -181,7 +191,10 @@ token(char *line, FILE *out, int *skip, int *unskip)
 	const char *this_cal_file;
 	int this_cal_line;
 
-	if (strncmp(line, "endif", 5) == 0) {
+	while (isspace(*line))
+		line++;
+
+	if (cmptoken(line, "endif")) {
 		if (*skip + *unskip == 0) {
 			WARN0("#endif without prior #ifdef or #ifndef");
 			return (T_ERR);
@@ -194,8 +207,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
 		return (T_OK);
 	}
 
-	if (strncmp(line, "ifdef", 5) == 0) {
-		walk = line + 5;
+	walk = cmptoken(line, "ifdef");
+	if (walk != NULL) {
 		sep = trimlr(&walk);
 
 		if (*walk == '\0') {
@@ -217,8 +230,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
 		return (T_OK);
 	}
 
-	if (strncmp(line, "ifndef", 6) == 0) {
-		walk = line + 6;
+	walk = cmptoken(line, "ifndef");
+	if (walk != NULL) {
 		sep = trimlr(&walk);
 
 		if (*walk == '\0') {
@@ -240,8 +253,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
 		return (T_OK);
 	}
 
-	if (strncmp(line, "else", 4) == 0) {
-		walk = line + 4;
+	walk = cmptoken(line, "else");
+	if (walk != NULL) {
 		(void)trimlr(&walk);
 
 		if (*walk != '\0') {
@@ -267,9 +280,8 @@ token(char *line, FILE *out, int *skip, int *unskip)
 	if (*skip != 0)
 		return (T_OK);
 
-	if (strncmp(line, "include", 7) == 0) {
-		walk = line + 7;
-
+	walk = cmptoken(line, "include");
+	if (walk != NULL) {
 		(void)trimlr(&walk);
 
 		if (*walk == '\0') {
@@ -306,10 +318,10 @@ token(char *line, FILE *out, int *skip, int *unskip)
 		return (T_OK);
 	}
 
-	if (strncmp(line, "define", 6) == 0) {
+	walk = cmptoken(line, "define");
+	if (walk != NULL) {
 		if (definitions == NULL)
 			definitions = sl_init();
-		walk = line + 6;
 		sep = trimlr(&walk);
 		*sep = '\0';
 
@@ -323,9 +335,9 @@ token(char *line, FILE *out, int *skip, int *unskip)
 		return (T_OK);
 	}
 
-	if (strncmp(line, "undef", 5) == 0) {
+	walk = cmptoken(line, "undef");
+	if (walk != NULL) {
 		if (definitions != NULL) {
-			walk = line + 5;
 			sep = trimlr(&walk);
 
 			if (*walk == '\0') {
@@ -345,10 +357,34 @@ token(char *line, FILE *out, int *skip, int *unskip)
 		return (T_OK);
 	}
 
-	return (T_PROCESS);
+	walk = cmptoken(line, "warning");
+	if (walk != NULL) {
+		(void)trimlr(&walk);
+		WARN1("Warning: %s", walk);
+	}
 
+	walk = cmptoken(line, "error");
+	if (walk != NULL) {
+		(void)trimlr(&walk);
+		WARN1("Error: %s", walk);
+		return (T_ERR);
+	}
+
+	WARN1("Undefined pre-processor command \"#%s\"", line);
+	return (T_ERR);
 }
 
+static void
+setup_locale(const char *locale)
+{
+	(void)setlocale(LC_ALL, locale);
+#ifdef WITH_ICONV
+	if (!doall)
+		set_new_encoding();
+#endif
+	setnnames();
+}
+
 #define	REPLACE(string, slen, struct_) \
 		if (strncasecmp(buf, (string), (slen)) == 0 && buf[(slen)]) { \
 			if (struct_.name != NULL)			      \
@@ -361,6 +397,7 @@ token(char *line, FILE *out, int *skip, int *unskip)
 static int
 cal_parse(FILE *in, FILE *out)
 {
+	char *mylocale = NULL;
 	char *line = NULL;
 	char *buf;
 	size_t linecap = 0;
@@ -459,12 +496,9 @@ cal_parse(FILE *in, FILE *out)
 		 * and does not run iconv(), this variable has little use.
 		 */
 		if (strncmp(buf, "LANG=", 5) == 0) {
-			(void)setlocale(LC_ALL, buf + 5);
-#ifdef WITH_ICONV
-			if (!doall)
-				set_new_encoding();
-#endif
-			setnnames();
+			if (mylocale == NULL)
+				mylocale = strdup(setlocale(LC_ALL, NULL));
+			setup_locale(buf + 5);
 			continue;
 		}
 		/* Parse special definitions: Easter, Paskha etc */
@@ -538,6 +572,10 @@ cal_parse(FILE *in, FILE *out)
 
 	free(line);
 	fclose(in);
+	if (mylocale != NULL) {
+		setup_locale(mylocale);
+		free(mylocale);
+	}
 
 	return (0);
 }


More information about the svn-src-head mailing list