*** generic/tclGet.c.orig Mon Sep 14 20:39:58 1998 --- generic/tclGet.c Wed Jul 14 19:43:00 1999 *************** *** 71,77 **** if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "expected integer but got \"", string, "\"", (char *) NULL); ! } return TCL_ERROR; } --- 71,78 ---- if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "expected integer but got \"", string, "\"", (char *) NULL); ! TclCheckBadOctal(interp, p); ! } return TCL_ERROR; } *************** *** 155,160 **** --- 156,162 ---- if (interp != (Tcl_Interp *) NULL) { Tcl_AppendResult(interp, "expected integer but got \"", string, "\"", (char *) NULL); + TclCheckBadOctal(interp, p); } return TCL_ERROR; } *** generic/tclObj.c.orig Tue Oct 06 00:32:08 1998 --- generic/tclObj.c Wed Jul 14 19:43:40 1999 *************** *** 1741,1746 **** --- 1741,1747 ---- sprintf(buf, "expected integer but got \"%.50s\"", string); Tcl_ResetResult(interp); Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1); + TclCheckBadOctal(interp, p); } return TCL_ERROR; } *** generic/tclExecute.c.orig Thu Nov 19 21:10:50 1998 --- generic/tclExecute.c Thu Jul 15 14:15:44 1999 *************** *** 3148,3153 **** --- 3148,3156 ---- "floating-point value" : "non-numeric string"), " as operand of \"", operatorStrings[opCode - INST_LOR], "\"", (char *) NULL); + if (opndPtr->typePtr != &tclDoubleType) { + TclCheckBadOctal(interp, Tcl_GetStringFromObj(opndPtr, NULL)); + } } } *** generic/tclUtil.c.orig Wed Jul 14 19:36:40 1999 --- generic/tclUtil.c Thu Jul 15 14:56:36 1999 *************** *** 2807,2818 **** --- 2807,2871 ---- Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "bad index \"", bytes, "\": must be integer or \"end\"", (char *) NULL); + TclCheckBadOctal(interp, bytes); } return result; } } *indexPtr = index; return TCL_OK; + } + + /* + *---------------------------------------------------------------------- + * + * TclCheckBadOctal -- + * + * This procedure checks for a bad octal value and appends a + * meaningful error to the interp's result. + * + * Results: + * 1 if the argument was a bad octal, else 0. + * + * Side effects: + * The interpreter's result is modified. + * + *---------------------------------------------------------------------- + */ + + int + TclCheckBadOctal(interp, value) + Tcl_Interp *interp; /* Interpreter to use for error reporting. + * If NULL, then no error message is left + * after errors. */ + char *value; /* String to check. */ + { + char *p; + + /* + * A frequent mistake is invalid octal values due to an unwanted + * leading zero. Try to generate a meaningful error message. + */ + + p = value; + if (*p == '+' || *p == '-') { + p++; + } + if (*p == '0') { + while (isdigit(UCHAR(*p))) { + p++; + } + if (*p == '\0') { + /* Reached end of string */ + if (interp) { + Tcl_AppendResult(interp, + "; \"", value, "\" uses an incorrect octal representation - see the expr man page", + (char *) NULL); + } + return 1; + } + } + return 0; } /* *** generic/tclCmdMZ.c.orig Mon Sep 14 20:39:56 1998 --- generic/tclCmdMZ.c Thu Jul 15 14:47:36 1999 *************** *** 1587,1592 **** --- 1587,1593 ---- Tcl_Obj *patternObj, *bodyObj; char *string, *pattern, *body; int splitObjs, length, patternLen, i, code, mode, matched, bodyIdx; + int seenComment; static char *switches[] = {"-exact", "-glob", "-regexp", "--", (char *) NULL}; *************** *** 1647,1657 **** --- 1648,1670 ---- splitObjs = 1; } + seenComment = 0; for (i = 0; i < switchObjc; i += 2) { if (i == (switchObjc-1)) { Tcl_ResetResult(interp); Tcl_AppendToObj(Tcl_GetObjResult(interp), "extra switch pattern with no body", -1); + + /* + * Check if this can be due to a badly placed comment + * in the switch block + */ + + if (splitObjs && seenComment) { + Tcl_AppendToObj(Tcl_GetObjResult(interp), + "; this can be due to a comment incorrectly placed outside a switch body - see the Tcl and switch man pages", -1); + } + code = TCL_ERROR; goto done; } *************** *** 1668,1673 **** --- 1681,1696 ---- pattern = Tcl_GetStringFromObj(patternObj, &patternLen); } else { pattern = Tcl_GetStringFromObj(switchObjv[i], &patternLen); + } + + /* + * The following is an heuristic to detect the infamous + * "comment in switch" error: just check if a pattern + * begins with '#'. + */ + + if (*pattern == '#') { + seenComment = 1; } matched = 0; *** generic/tclInt.h.orig Wed Feb 03 22:28:00 1999 --- generic/tclInt.h Wed Jul 14 19:42:12 1999 *************** *** 1427,1432 **** --- 1427,1434 ---- EXTERN void TclAllocateFreeObjects _ANSI_ARGS_((void)); EXTERN int TclChdir _ANSI_ARGS_((Tcl_Interp *interp, char *dirName)); + EXTERN int TclCheckBadOctal _ANSI_ARGS_((Tcl_Interp *interp, + char *value)); EXTERN int TclCleanupChildren _ANSI_ARGS_((Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan));