Author: se
Date: Sat Oct 31 15:11:24 2020
New Revision: 367207
URL: https://svnweb.freebsd.org/changeset/base/367207

Log:
  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

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

Modified: head/usr.bin/calendar/io.c
==============================================================================
--- head/usr.bin/calendar/io.c  Sat Oct 31 14:59:39 2020        (r367206)
+++ head/usr.bin/calendar/io.c  Sat Oct 31 15:11:24 2020        (r367207)
@@ -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,10 +286,28 @@ 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);
+       }
+
        return (T_PROCESS);
 
 }
@@ -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,12 +506,15 @@ 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);
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to