[comp.bugs.4bsd] calendar

hoey@ai.etl.army.mil (Dan Hoey) (05/13/88)

Index:	usr.bin/calendar/calendar.c 4.3BSD +FIX

Description:
	On some Fridays calendar(1) says ``egrep: regular expression too
	long.''  This is because /usr/lib/calendar makes a regular expression
	that is too long.  It only happens on Fridays because the pattern has
	to match four days on Fridays.

	I have only observed this problem near the end of the month, and it
	isn't happening today (13 May).  I don't know why it only happens on
	some Fridays.  It definitely happens when the date is Friday 29 April.

	I sent in a fix for this for 4.2 but the bug was still there in 4.3.
	I sent in a fix for 4.3, but I haven't seen it here, so this is my
	latest attempt to find out what price I have to pay to get out of
	going through all these things twice.

Repeat-By:
	On Friday 29 April type "calendar".

Fix:
	The pattern can be made smaller by grouping some common parts with
	parentheses.  This fix also allows dates of the form "*/5" to match
	the fifth of any month just like "* 5" does.  Note that it is unwise
	to mention "*/5" inside a C comment.

	Of course, this can be fixed by fixing egrep's idea of what a regular
	expression's maximum size is, but I don't see why we shouldn't fix
	calendar, too.  Someone else can show how to fix egrep.

	Context diff:

*** /tmp/,RCSt1028981	Fri Apr 29 09:34:42 1988
--- calendar.c	Fri Apr 29 09:34:24 1988
***************
*** 1,4
! static	char *sccsid = "@(#)calendar.c	4.5 (Berkeley) 84/05/07";
  /* /usr/lib/calendar produces an egrep -f file
     that will select today's and tomorrow's
     calendar entries, with special weekend provisions

--- 1,4 -----
! static	char *sccsid = "@(#)calendar.c	4.>5 (Hoey) 88/04/29";
  /* /usr/lib/calendar produces an egrep -f file
     that will select today's and tomorrow's
     calendar entries, with special weekend provisions
***************
*** 4,9
     calendar entries, with special weekend provisions
  
     used by calendar command
  */
  #include <sys/time.h>
  

--- 4,12 -----
     calendar entries, with special weekend provisions
  
     used by calendar command
+ 
+    Modified to minimize pattern size so egrep won't barf.  Also allow
+    wild-card dates in slash format.
  */
  #include <sys/time.h>
  
***************
*** 25,30
  };
  struct tm *localtime();
  
  tprint(t)
  long t;
  {

--- 28,36 -----
  };
  struct tm *localtime();
  
+ int disjunct = 0; /* True if we are working on second or later disjunct of
+ 			the pattern. */
+ 
  tprint(t)
  long t;
  {
***************
*** 30,36
  {
  	struct tm *tm;
  	tm = localtime(&t);
! 	printf("(^|[ 	(,;])((%s[^ \t]*[ \t]*|(0%d|%d)/)0*%d)([^0123456789]|$)\n",
  		month[tm->tm_mon],
  		tm->tm_mon + 1, tm->tm_mon + 1, tm->tm_mday);
  	printf("(^|[ 	(,;])((\\*[ \t]*)0*%d)([^0123456789]|$)\n",

--- 36,51 -----
  {
  	struct tm *tm;
  	tm = localtime(&t);
! 	if (!disjunct) {
! 	    /* Pattern for start of date and open parenthesis */
! 	    printf("(^|[ \t(,;])(");
! 	    disjunct = 1;
! 	} else {
! 	    /* Next date */
! 	    printf ("\n");
! 	}
! 	/* [Jj]an 5 or \* 5 or 1/5 */
! 	printf("((%s[^ \t]*|\\*)[ \t]*|(0*%d|\\*)/)0*%d",
  		month[tm->tm_mon],
  		tm->tm_mon + 1, tm->tm_mday);
  }
***************
*** 32,40
  	tm = localtime(&t);
  	printf("(^|[ 	(,;])((%s[^ \t]*[ \t]*|(0%d|%d)/)0*%d)([^0123456789]|$)\n",
  		month[tm->tm_mon],
! 		tm->tm_mon + 1, tm->tm_mon + 1, tm->tm_mday);
! 	printf("(^|[ 	(,;])((\\*[ \t]*)0*%d)([^0123456789]|$)\n",
! 		tm->tm_mday);
  }
  
  main()

--- 47,53 -----
  	/* [Jj]an 5 or \* 5 or 1/5 */
  	printf("((%s[^ \t]*|\\*)[ \t]*|(0*%d|\\*)/)0*%d",
  		month[tm->tm_mon],
! 		tm->tm_mon + 1, tm->tm_mday);
  }
  
  main()
***************
*** 53,56
  		t += DAY;
  		tprint(t);
  	}
  }

--- 66,71 -----
  		t += DAY;
  		tprint(t);
  	}
+ 	/* End of date.  Make sure date ends cleanly. */
+ 	printf(")([^0-9]|$)\n");
  }