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"); }