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

Reply via email to