Description: The new ctime distributed in March of 1987 uses an undocumented printf formating directive ("%.2d") and a `precision' specification in a string formating directive ("%.3s"). The VAX doprnt interprets "%.2d" to mean "%02d". The "%.3s" format is not an error, but does cause the user contributed editor jove to misbehave (the "%.2d" also causes jove problems). Repeat-By: Try to compile and use the new ctime on a system which doesn't support the VAX "%.2d" semantics. Try to compile and run jove with the new ctime. Fix: Following are fixes to ctime.c, jove/io.c and jove/fmt.c. The fix to jove/io.c is one that jove's author, Jon Payne, published to fix a buffer management problem. % diff -c ctime.c-bad ctime.c *** ctime.c-bad Tue Apr 7 19:46:28 1987 --- ctime.c Tue Apr 7 19:46:54 1987 *************** *** 39,45 **** }; static char result[26]; ! (void) sprintf(result, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n", wday_name[timeptr->tm_wday], mon_name[timeptr->tm_mon], timeptr->tm_mday, timeptr->tm_hour, --- 39,45 ---- }; static char result[26]; ! (void) sprintf(result, "%.3s %.3s%3d %02d:%02d:%02d %d\n", wday_name[timeptr->tm_wday], mon_name[timeptr->tm_mon], timeptr->tm_mday, timeptr->tm_hour, % diff -c io.c-bad io.c *** io.c-bad Tue Apr 7 19:45:06 1987 --- io.c Tue Apr 7 19:30:38 1987 *************** *** 862,869 **** if (bno >= NMBLKS) error("Tmp file too large. Get help!"); nleft = BUFSIZ - off; ! if (lastb != 0 && lastb->b_bno == bno) return lastb->b_buf + off; /* The requested block already lives in memory, so we move it to the end of the LRU list (making it Most Recently Used) --- 862,871 ---- if (bno >= NMBLKS) error("Tmp file too large. Get help!"); nleft = BUFSIZ - off; ! if (lastb != 0 && lastb->b_bno == bno) { ! lastb->b_dirty |= iof; return lastb->b_buf + off; + } /* The requested block already lives in memory, so we move it to the end of the LRU list (making it Most Recently Used) % diff -c fmt.c-bad fmt.c *** fmt.c-bad Tue Apr 7 19:44:58 1987 --- fmt.c Tue Apr 7 19:54:48 1987 *************** *** 56,67 **** } static ! putld(leftadj, width, d, base) long d; { int length = 1; long tmpd = d; while (tmpd = (tmpd / base)) length++; if (d < 0) --- 56,78 ---- } static ! putld(leftadj, width, precision, d, base) long d; { int length = 1; long tmpd = d; while (tmpd = (tmpd / base)) length++; if (d < 0) *************** *** 89,100 **** } static ! puts(leftadj, width, str) char *str; { int length; ! register char *cp, ! c; if (str == 0) #if pyr --- 100,110 ---- } static ! puts(leftadj, width, precision, str) char *str; { int length; ! register char *cp; if (str == 0) #if pyr *************** *** 103,113 **** str = "(null)"; #endif length = strlen(str); cp = str; if (!leftadj) pad(' ', width - length); ! while (c = *cp++) ! putc(c, curiop); if (leftadj) pad(' ', width - length); } --- 113,128 ---- str = "(null)"; #endif length = strlen(str); + if (precision == 0 || length < precision) + precision = length; + else + length = precision; + cp = str; if (!leftadj) pad(' ', width - length); ! while (precision--) ! putc(*cp++, curiop); if (leftadj) pad(' ', width - length); } *************** *** 129,135 **** { register char c; int leftadj, ! width; File *pushiop = curiop; curiop = sp; --- 144,151 ---- { register char c; int leftadj, ! width, ! precision; File *pushiop = curiop; curiop = sp; *************** *** 141,147 **** } padc = ' '; ! leftadj = width = 0; c = *fmt++; if (c == '-') { leftadj++; --- 157,163 ---- } padc = ' '; ! leftadj = width = precision = 0; c = *fmt++; if (c == '-') { leftadj++; *************** *** 159,164 **** --- 175,191 ---- width = va_arg(ap, int); c = *fmt++; } + if (c == '.') { + c = *fmt++; + while (c >= '0' && c <= '9') { + precision = precision * 10 + (c - '0'); + c = *fmt++; + } + if (c == '*') { + precision = va_arg(ap, int); + c = *fmt++; + } + } reswitch: /* At this point, fmt points at one past the format letter. */ switch (c) { *************** *** 171,185 **** break; case 'o': ! putld(leftadj, width, (long) va_arg(ap, int), 8); break; case 'd': ! putld(leftadj, width, (long) va_arg(ap, int), 10); break; case 'D': ! putld(leftadj, width, va_arg(ap, long), 10); break; case 'p': --- 198,212 ---- break; case 'o': ! putld(leftadj, width, precision, (long) va_arg(ap, int), 8); break; case 'd': ! putld(leftadj, width, precision, (long) va_arg(ap, int), 10); break; case 'D': ! putld(leftadj, width, precision, va_arg(ap, long), 10); break; case 'p': *************** *** 187,203 **** char cbuf[20]; PPchar(va_arg(ap, int), cbuf); ! puts(leftadj, width, cbuf); break; } case 'n': if (va_arg(ap, int) != 1) ! puts(leftadj, width, "s"); break; case 's': ! puts(leftadj, width, va_arg(ap, char *)); break; case 'c': --- 214,230 ---- char cbuf[20]; PPchar(va_arg(ap, int), cbuf); ! puts(leftadj, width, precision, cbuf); break; } case 'n': if (va_arg(ap, int) != 1) ! puts(leftadj, width, precision, "s"); break; case 's': ! puts(leftadj, width, precision, va_arg(ap, char *)); break; case 'c': *************** *** 205,211 **** break; case 'f': /* current command name gets inserted here! */ ! puts(leftadj, width, LastCmd->Name); break; default: --- 232,238 ---- break; case 'f': /* current command name gets inserted here! */ ! puts(leftadj, width, precision, LastCmd->Name); break; default: