From 260c5156ed0ec2b944268320a267cee9a57cd547 Mon Sep 17 00:00:00 2001 From: dgp Date: Sun, 18 Sep 2022 13:59:26 +0000 Subject: TIP implementation to add/use public routines Tcl_GetNumber(FromObj). --- generic/tcl.decls | 8 ++++++++ generic/tcl.h | 14 ++++++++++++++ generic/tclBasic.c | 32 ++++++++++++++++---------------- generic/tclDecls.h | 14 ++++++++++++++ generic/tclExecute.c | 4 ++-- generic/tclInt.h | 18 ------------------ generic/tclLink.c | 2 +- generic/tclObj.c | 40 ++++++++++++++++++++++++++++++++++++++-- generic/tclStubInit.c | 2 ++ generic/tclUtil.c | 10 +++++----- 10 files changed, 100 insertions(+), 44 deletions(-) diff --git a/generic/tcl.decls b/generic/tcl.decls index d08ba0a..2bbad1c 100644 --- a/generic/tcl.decls +++ b/generic/tcl.decls @@ -2523,6 +2523,14 @@ declare 679 { int Tcl_NRCallObjProc2(Tcl_Interp *interp, Tcl_ObjCmdProc2 *objProc2, void *clientData, size_t objc, Tcl_Obj *const objv[]) } +declare 680 { + int Tcl_GetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, + void **clientDataPtr, int *typePtr) +} +declare 681 { + int Tcl_GetNumber(Tcl_Interp *interp, const char *bytes, size_t numBytes, + void **clientDataPtr, int *typePtr) +} # ----- BASELINE -- FOR -- 8.7.0 ----- # diff --git a/generic/tcl.h b/generic/tcl.h index f17d43e..cd16ea9 100644 --- a/generic/tcl.h +++ b/generic/tcl.h @@ -974,6 +974,20 @@ typedef struct Tcl_DString { #define TCL_INTEGER_SPACE (3*(int)sizeof(Tcl_WideInt)) /* + *---------------------------------------------------------------------------- + * Type values returned by Tcl_GetNumberFromObj + * TCL_NUMBER_INT Representation is a Tcl_WideInt + * TCL_NUMBER_BIG Representation is an mp_int + * TCL_NUMBER_DOUBLE Representation is a double + * TCL_NUMBER_NAN Value is NaN. + */ + +#define TCL_NUMBER_INT 2 +#define TCL_NUMBER_BIG 3 +#define TCL_NUMBER_DOUBLE 4 +#define TCL_NUMBER_NAN 5 + +/* * Flag values passed to Tcl_ConvertElement. * TCL_DONT_USE_BRACES forces it not to enclose the element in braces, but to * use backslash quoting instead. diff --git a/generic/tclBasic.c b/generic/tclBasic.c index b806c33..d7afc14 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -4133,7 +4133,7 @@ OldMathFuncProc( args = (Tcl_Value *)ckalloc(dataPtr->numArgs * sizeof(Tcl_Value)); for (j = 1, k = 0; j < objc; ++j, ++k) { - /* TODO: Convert to TclGetNumberFromObj? */ + /* TODO: Convert to Tcl_GetNumberFromObj? */ valuePtr = objv[j]; result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d); #ifdef ACCEPT_NAN @@ -7041,7 +7041,7 @@ Tcl_ExprLongObj( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type)!=TCL_OK) { + if (Tcl_GetNumberFromObj(interp, resultPtr, &internalPtr, &type)!=TCL_OK) { return TCL_ERROR; } @@ -7087,7 +7087,7 @@ Tcl_ExprDoubleObj( return TCL_ERROR; } - result = TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type); + result = Tcl_GetNumberFromObj(interp, resultPtr, &internalPtr, &type); if (result == TCL_OK) { switch (type) { case TCL_NUMBER_NAN: @@ -7808,7 +7808,7 @@ ExprIsqrtFunc( * Make sure that the arg is a number. */ - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } @@ -8071,7 +8071,7 @@ ExprAbsFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } @@ -8226,7 +8226,7 @@ ExprIntFunc( MathFuncWrongNumArgs(interp, 2, objc, objv); return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } @@ -8307,7 +8307,7 @@ ExprMaxMinFunc( } res = objv[1]; for (i = 1; i < objc; i++) { - if (TclGetNumberFromObj(interp, objv[i], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[i], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type == TCL_NUMBER_NAN) { @@ -8459,7 +8459,7 @@ ExprRoundFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } @@ -8727,7 +8727,7 @@ ExprIsFiniteFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type != TCL_NUMBER_NAN) { @@ -8758,7 +8758,7 @@ ExprIsInfinityFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type != TCL_NUMBER_NAN) { @@ -8788,7 +8788,7 @@ ExprIsNaNFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type != TCL_NUMBER_NAN) { @@ -8818,7 +8818,7 @@ ExprIsNormalFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type != TCL_NUMBER_NAN) { @@ -8848,7 +8848,7 @@ ExprIsSubnormalFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type != TCL_NUMBER_NAN) { @@ -8878,7 +8878,7 @@ ExprIsUnorderedFunc( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type == TCL_NUMBER_NAN) { @@ -8888,7 +8888,7 @@ ExprIsUnorderedFunc( result = (ClassifyDouble(d) == FP_NAN); } - if (TclGetNumberFromObj(interp, objv[2], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[2], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type == TCL_NUMBER_NAN) { @@ -8920,7 +8920,7 @@ FloatClassifyObjCmd( return TCL_ERROR; } - if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { + if (Tcl_GetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) { return TCL_ERROR; } if (type == TCL_NUMBER_NAN) { diff --git a/generic/tclDecls.h b/generic/tclDecls.h index 3917d0f..82d592b 100644 --- a/generic/tclDecls.h +++ b/generic/tclDecls.h @@ -1996,6 +1996,14 @@ EXTERN Tcl_Command Tcl_NRCreateCommand2(Tcl_Interp *interp, EXTERN int Tcl_NRCallObjProc2(Tcl_Interp *interp, Tcl_ObjCmdProc2 *objProc2, void *clientData, size_t objc, Tcl_Obj *const objv[]); +/* 680 */ +EXTERN int Tcl_GetNumberFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr, void **clientDataPtr, + int *typePtr); +/* 681 */ +EXTERN int Tcl_GetNumber(Tcl_Interp *interp, const char *bytes, + size_t numBytes, void **clientDataPtr, + int *typePtr); typedef struct { const struct TclPlatStubs *tclPlatStubs; @@ -2711,6 +2719,8 @@ typedef struct TclStubs { Tcl_Trace (*tcl_CreateObjTrace2) (Tcl_Interp *interp, int level, int flags, Tcl_CmdObjTraceProc2 *objProc2, void *clientData, Tcl_CmdObjTraceDeleteProc *delProc); /* 677 */ Tcl_Command (*tcl_NRCreateCommand2) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc2 *proc, Tcl_ObjCmdProc2 *nreProc2, void *clientData, Tcl_CmdDeleteProc *deleteProc); /* 678 */ int (*tcl_NRCallObjProc2) (Tcl_Interp *interp, Tcl_ObjCmdProc2 *objProc2, void *clientData, size_t objc, Tcl_Obj *const objv[]); /* 679 */ + int (*tcl_GetNumberFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, void **clientDataPtr, int *typePtr); /* 680 */ + int (*tcl_GetNumber) (Tcl_Interp *interp, const char *bytes, size_t numBytes, void **clientDataPtr, int *typePtr); /* 681 */ } TclStubs; extern const TclStubs *tclStubsPtr; @@ -4099,6 +4109,10 @@ extern const TclStubs *tclStubsPtr; (tclStubsPtr->tcl_NRCreateCommand2) /* 678 */ #define Tcl_NRCallObjProc2 \ (tclStubsPtr->tcl_NRCallObjProc2) /* 679 */ +#define Tcl_GetNumberFromObj \ + (tclStubsPtr->tcl_GetNumberFromObj) /* 680 */ +#define Tcl_GetNumber \ + (tclStubsPtr->tcl_GetNumber) /* 681 */ #endif /* defined(USE_TCL_STUBS) */ diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 8aa3bb2..dc5adc2 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -502,7 +502,7 @@ VarHashCreateVar( /* * Macro used in this file to save a function call for common uses of - * TclGetNumberFromObj(). The ANSI C "prototype" is: + * Tcl_GetNumberFromObj(). The ANSI C "prototype" is: * * MODULE_SCOPE int GetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, * void **ptrPtr, int *tPtr); @@ -521,7 +521,7 @@ VarHashCreateVar( (&((objPtr)->internalRep.doubleValue)), TCL_OK) : \ (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)) \ ? TCL_ERROR : \ - TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) + Tcl_GetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr))) /* * Macro used to make the check for type overflow more mnemonic. This works by diff --git a/generic/tclInt.h b/generic/tclInt.h index 09f22d3..9eba8c5 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2875,21 +2875,6 @@ typedef struct ProcessGlobalValue { /* Reject underscore digit separator */ /* - *---------------------------------------------------------------------- - * Type values TclGetNumberFromObj - *---------------------------------------------------------------------- - */ - -#define TCL_NUMBER_INT 2 -#if !defined(TCL_NO_DEPRECATED) -# define TCL_NUMBER_LONG 1 /* deprecated, not used any more */ -# define TCL_NUMBER_WIDE TCL_NUMBER_INT /* deprecated */ -#endif -#define TCL_NUMBER_BIG 3 -#define TCL_NUMBER_DOUBLE 4 -#define TCL_NUMBER_NAN 5 - -/* *---------------------------------------------------------------- * Variables shared among Tcl modules but not used by the outside world. *---------------------------------------------------------------- @@ -3199,9 +3184,6 @@ MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp, Tcl_Obj *value, int *code); MODULE_SCOPE Proc * TclGetLambdaFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **nsObjPtrPtr); -MODULE_SCOPE int TclGetNumberFromObj(Tcl_Interp *interp, - Tcl_Obj *objPtr, void **clientDataPtr, - int *typePtr); MODULE_SCOPE int TclGetOpenModeEx(Tcl_Interp *interp, const char *modeString, int *seekFlagPtr, int *binaryPtr); diff --git a/generic/tclLink.c b/generic/tclLink.c index 6bd65fa..0d57d44 100644 --- a/generic/tclLink.c +++ b/generic/tclLink.c @@ -530,7 +530,7 @@ GetUWide( void *clientData; int type, intValue; - if (TclGetNumberFromObj(NULL, objPtr, &clientData, &type) == TCL_OK) { + if (Tcl_GetNumberFromObj(NULL, objPtr, &clientData, &type) == TCL_OK) { if (type == TCL_NUMBER_INT) { *widePtr = *((const Tcl_WideInt *) clientData); return (*widePtr < 0); diff --git a/generic/tclObj.c b/generic/tclObj.c index 5726596..f9b5bd3 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -3856,7 +3856,7 @@ TclSetBignumInternalRep( /* *---------------------------------------------------------------------- * - * TclGetNumberFromObj -- + * Tcl_GetNumberFromObj -- * * Extracts a number (of any possible numeric type) from an object. * @@ -3874,7 +3874,7 @@ TclSetBignumInternalRep( */ int -TclGetNumberFromObj( +Tcl_GetNumberFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, ClientData *clientDataPtr, @@ -3909,6 +3909,42 @@ TclGetNumberFromObj( TclParseNumber(interp, objPtr, "number", NULL, -1, NULL, 0)); return TCL_ERROR; } + +int +Tcl_GetNumber( + Tcl_Interp *interp, + const char *bytes, + size_t numBytes, + ClientData *clientDataPtr, + int *typePtr) +{ + static Tcl_ThreadDataKey numberCacheKey; + Tcl_Obj *objPtr = (Tcl_Obj *)Tcl_GetThreadData(&numberCacheKey, + sizeof(Tcl_Obj)); + + Tcl_FreeInternalRep(objPtr); + + if (bytes == NULL) { + bytes = &tclEmptyString; + numBytes = 0; + } + if (numBytes == (size_t)TCL_INDEX_NONE) { + numBytes = strlen(bytes); + } + if (numBytes > INT_MAX) { + if (interp) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "max size for a Tcl value (%d bytes) exceeded", INT_MAX)); + Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); + } + return TCL_ERROR; + } + + objPtr->bytes = (char *) bytes; + objPtr->length = numBytes; + + return Tcl_GetNumberFromObj(interp, objPtr, clientDataPtr, typePtr); +} /* *---------------------------------------------------------------------- diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c index ae00b04..4e6041e 100644 --- a/generic/tclStubInit.c +++ b/generic/tclStubInit.c @@ -2043,6 +2043,8 @@ const TclStubs tclStubs = { Tcl_CreateObjTrace2, /* 677 */ Tcl_NRCreateCommand2, /* 678 */ Tcl_NRCallObjProc2, /* 679 */ + Tcl_GetNumberFromObj, /* 680 */ + Tcl_GetNumber, /* 681 */ }; /* !END!: Do not edit above this line. */ diff --git a/generic/tclUtil.c b/generic/tclUtil.c index 7ab6eae..742bded 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -3644,7 +3644,7 @@ GetWideForIndex( { int numType; ClientData cd; - int code = TclGetNumberFromObj(NULL, objPtr, &cd, &numType); + int code = Tcl_GetNumberFromObj(NULL, objPtr, &cd, &numType); if (code == TCL_OK) { if (numType == TCL_NUMBER_INT) { @@ -3803,7 +3803,7 @@ GetEndOffsetFromObj( /* ... value continues with [-+] ... */ /* Save first integer as wide if possible */ - TclGetNumberFromObj(NULL, objPtr, &cd, &t1); + Tcl_GetNumberFromObj(NULL, objPtr, &cd, &t1); if (t1 == TCL_NUMBER_INT) { w1 = (*(Tcl_WideInt *)cd); } @@ -3813,7 +3813,7 @@ GetEndOffsetFromObj( /* ... value concludes with second valid integer */ /* Save second integer as wide if possible */ - TclGetNumberFromObj(NULL, objPtr, &cd, &t2); + Tcl_GetNumberFromObj(NULL, objPtr, &cd, &t2); if (t2 == TCL_NUMBER_INT) { w2 = (*(Tcl_WideInt *)cd); } @@ -3866,7 +3866,7 @@ GetEndOffsetFromObj( Tcl_ExprObj(compute, objPtr, &sum); Tcl_DeleteInterp(compute); } - TclGetNumberFromObj(NULL, sum, &cd, &numType); + Tcl_GetNumberFromObj(NULL, sum, &cd, &numType); if (numType == TCL_NUMBER_INT) { /* sum holds an integer in the signed wide range */ @@ -3917,7 +3917,7 @@ GetEndOffsetFromObj( } /* Got an integer offset; pull it from where parser left it. */ - TclGetNumberFromObj(NULL, objPtr, &cd, &t); + Tcl_GetNumberFromObj(NULL, objPtr, &cd, &t); if (t == TCL_NUMBER_BIG) { /* Truncate to the signed wide range. */ -- cgit v0.12 From 414f4c9f7c689e4c1cba2c4f568db0ff3b5df688 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 28 Sep 2022 18:41:42 +0000 Subject: WIP on documentation of proposed routines. --- doc/Number.3 | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 doc/Number.3 diff --git a/doc/Number.3 b/doc/Number.3 new file mode 100644 index 0000000..588171e --- /dev/null +++ b/doc/Number.3 @@ -0,0 +1,88 @@ +'\" +'\" Contribution from Don Porter, NIST, 2022. (not subject to US copyright) +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +.TH Tcl_GetNumber 3 8.7 Tcl "Tcl Library Procedures" +.so man.macros +.BS +.SH NAME +Tcl_GetNumber, Tcl_GetNumberFromObj \- get numeric value from Tcl value +.SH SYNOPSIS +.nf +\fB#include \fR +.sp +\fB#include \fR +.sp +int +\fBTcl_GetNumber\fR(\fIinterp, bytes, numBytes, clientDataPtr, typePtr\fR) +.sp +int +\fBTcl_GetNumberFromObj\fR(\fIinterp, objPtr, clientDataPtr, typePtr\fR) +.SH ARGUMENTS +.AS Tcl_Interp clientDataPtr out +.AP Tcl_Interp *interp out +When non-NULL, error information is recorded here when the value is not +in any of the numeric formats recognized by Tcl. +.AP "const char" *bytes in +Points to first byte of the string value to be examined. +.AP size_t numBytes in +The number of bytes, starting at \fIbytes\fR, that should be examined. +If the value \fBTCL_INDEX_NONE\fR is provided, then all bytes should +be examined until the first \fBNUL\fR byte terminates examination. +.AP "void *" *clientDataPtr out +Points to space where a pointer value may be written through which a numeric +value is available to read. +.AP int *typePtr out +Points to space where a value may be written reporting what type of +numeric storage is available to read. +.AP Tcl_Obj *objPtr in +A Tcl value to be examined. +.BE +.SH DESCRIPTION +.PP +These procedures enable callers to retrieve a numeric value from a +Tcl value in a numeric format recognized by Tcl. +.PP +Tcl recognizes many values as numbers. Several examples include: +\fB"0"\fR, \fB" +1"\fR, \fB"-2 "\fR, \fB" 3 "\fR, \fB"0xdad1"\fR, \fB"0d09"\fR, +\fB"1_000_000"\fR, \fB"4.0"\fR, \fB"1e-7"\fR, \fB"NaN"\fR, or \fB"Inf"\fR. +When built-in Tcl commands act on these values as numbers, they are converted +to a numeric representation for efficient handling in C code. Tcl makes +use of three C types to store these representations: \fBdouble\fR, +\fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBdouble\fR type is provided by the +C language standard. The \fBTcl_WideInt\fR type is declared in the Tcl +header file, \fBtcl.h\fR, and is equivalent to the C standard type +\fBlong long\fR on most platforms. The \fBmp_int\fR type is declared in the +header file \fBtclTomMath.h\fR, and implemented by the LibTomMath +multiple-precision integer library, included with Tcl. + +The routines \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR perform +the same function. They differ only in how the arguments present the Tcl +value to be examined. \fBTcl_GetNumber\fR accepts a counted string +value in the arguments \fIbytes\fR and \fInumBytes\fR (or a +\fBNUL\fR-terminated string value when \fInumBytes\fR is +\fBTCL_INDEX_NONE\fR). \fBTcl_GetNumberFromObj\fR accepts the Tcl value +in \fIobjPtr\fR. + +Both routines examine the Tcl value and determine whether Tcl recognizes +it as a number. If not, both routines return \fBTCL_ERROR\fR and (when +\fIinterp\fR is not NULL) record an error message and error code +in \fIinterp\fR. + +If the examined value is recognized as a number, both routines return +\fBTCL_OK\fR, and use the pointer arguments \fIclientDataPtr\fR +and \fItypePtr\fR (which may not be NULL) to report information the +caller can use to retrieve the numeric representation. In all cases, +both routines write to *\fIclientDataPtr\fR a pointer to the internal +storage location where Tcl holds the numeric value. When that +internal storage is of type \fBdouble\fR + + + +.SH "SEE ALSO" +Tcl_GetDouble, Tcl_GetDoubleFromObj, Tcl_GetWideIntFromObj +.SH KEYWORDS +double, double value, double type, integer, integer value, integer type, +internal representation, value, value type, string representation -- cgit v0.12 From 9e7c607db1c09acf473b8b10df55452b1e907499 Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 29 Sep 2022 20:53:43 +0000 Subject: Complete documentation for the TIP 638 routines. --- doc/Number.3 | 53 ++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/doc/Number.3 b/doc/Number.3 index 65a1332..f93d75d 100644 --- a/doc/Number.3 +++ b/doc/Number.3 @@ -57,7 +57,7 @@ header file, \fBtcl.h\fR, and is equivalent to the C standard type \fBlong long\fR on most platforms. The \fBmp_int\fR type is declared in the header file \fBtclTomMath.h\fR, and implemented by the LibTomMath multiple-precision integer library, included with Tcl. - +.PP The routines \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR perform the same function. They differ only in how the arguments present the Tcl value to be examined. \fBTcl_GetNumber\fR accepts a counted string @@ -65,22 +65,57 @@ value in the arguments \fIbytes\fR and \fInumBytes\fR (or a \fBNUL\fR-terminated string value when \fInumBytes\fR is \fBTCL_INDEX_NONE\fR). \fBTcl_GetNumberFromObj\fR accepts the Tcl value in \fIobjPtr\fR. - +.PP Both routines examine the Tcl value and determine whether Tcl recognizes it as a number. If not, both routines return \fBTCL_ERROR\fR and (when \fIinterp\fR is not NULL) record an error message and error code in \fIinterp\fR. - -If the examined value is recognized as a number, both routines return +.PP +If Tcl does recognize the examined value as a number, both routines return \fBTCL_OK\fR, and use the pointer arguments \fIclientDataPtr\fR and \fItypePtr\fR (which may not be NULL) to report information the caller can use to retrieve the numeric representation. Both routines write to *\fIclientDataPtr\fR a pointer to the internal storage location -where Tcl holds the converted numeric value. When that internal storage -is of type \fBdouble\fR - - - +where Tcl holds the converted numeric value. +.PP +When the converted numeric value is stored as a \fBdouble\fR, +a call to math library routine \fBisnan\fR determines whether that +value is not a number (NaN). If so, both \fBTcl_GetNumber\fR and +\fBTcl_GetNumberFromObj\fR write the value \fBTCL_NUMBER_NAN\fR +to *\fItypePtr\fR. If not, both routines write the value +\fBTCL_NUMBER_DOUBLE\fR to *\fItypePtr\fR. These routines report +different type values in these cases because \fBTcl_GetDoubleFromObj\fR +raises an error on NaN values. For both reported type values, +the storage pointer may be cast to type \fBconst double *\fR and +the \fBdouble\fR numeric value may be read through it. +.PP +When the converted numeric value is stored as a \fBTcl_WideInt\fR, +both \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR write the +value \fBTCL_NUMBER_INT\fR to *\fItypePtr\fR. +The storage pointer may be cast to type \fBconst Tcl_WideInt *\fR and +the \fBTcl_WideInt\fR numeric value may be read through it. +.PP +When the converted numeric value is stored as an \fBmp_int\fR, +both \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR write the +value \fBTCL_NUMBER_BIG\fR to *\fItypePtr\fR. +The storage pointer may be cast to type \fBconst mp_int *\fR and +the \fBmp_int\fR numeric value may be read through it. +.PP +Future releases of Tcl might expand or revise the recognition of +values as numbers. If additional storage representations are +adopted, these routines will add new values to be written to +*\fItypePtr\fR to identify them. Callers should consider how +they should react to unknown values written to *\fItypePtr\fR. +.PP +When callers of these routines read numeric values through the +reported storage pointer, they are accessing memory that belongs +to the Tcl library. The Tcl library has the power to overwrite +or free this memory. The storage pointer reported by a call to +\fBTcl_GetNumber\fR or \fBTcl_GetNumberFromObj\fR should not be +used after the same thread has possibly returned control to the +Tcl library. If longer term access to the numeric value is needed, +it should be copied into memory controlled by the caller. Callers +must not attempt to write through or free the storage pointer. .SH "SEE ALSO" Tcl_GetDouble, Tcl_GetDoubleFromObj, Tcl_GetWideIntFromObj .SH KEYWORDS -- cgit v0.12 From 4addfd1f1e4fe9475c50be231c97bea3ffb086f1 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 12 Oct 2022 16:04:12 +0000 Subject: Extract TIP #637 implementation from "novem" branch --- doc/glob.n | 4 +-- generic/tclFileName.c | 54 +++++++++++--------------------------- generic/tclInt.h | 13 ---------- library/package.tcl | 3 +++ tests/fCmd.test | 8 +++--- tests/fileName.test | 72 +++++++++++++++++++++++++-------------------------- tests/winFile.test | 2 +- 7 files changed, 61 insertions(+), 95 deletions(-) diff --git a/doc/glob.n b/doc/glob.n index 8a3099e..80610f7 100644 --- a/doc/glob.n +++ b/doc/glob.n @@ -46,8 +46,8 @@ separators. .TP \fB\-nocomplain\fR . -Allows an empty list to be returned without error; without this -switch an error is returned if the result list would be empty. +Allows an empty list to be returned without error; This is the +default behavior in Tcl 9.0, so this switch has no effect any more. .TP \fB\-path\fR \fIpathPrefix\fR . diff --git a/generic/tclFileName.c b/generic/tclFileName.c index 408d295..040f0fd 100644 --- a/generic/tclFileName.c +++ b/generic/tclFileName.c @@ -35,6 +35,14 @@ static Tcl_Obj * SplitUnixPath(const char *path); static int DoGlob(Tcl_Interp *interp, Tcl_Obj *resultPtr, const char *separators, Tcl_Obj *pathPtr, int flags, char *pattern, Tcl_GlobTypeData *types); +static int TclGlob(Tcl_Interp *interp, char *pattern, + Tcl_Obj *pathPrefix, int globFlags, + Tcl_GlobTypeData *types); + +/* Flag values used by TclGlob() */ + +#define TCL_GLOBMODE_DIR 4 +#define TCL_GLOBMODE_TAILS 8 /* * When there is no support for getting the block size of a file in a stat() @@ -1132,8 +1140,8 @@ Tcl_GlobObjCmd( dir = PATH_NONE; typePtr = NULL; for (i = 1; i < objc; i++) { - if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, - &index) != TCL_OK) { + if (Tcl_GetIndexFromObj(interp, objv[i], options, + "option", 0, &index) != TCL_OK) { string = TclGetString(objv[i]); if (string[0] == '-') { /* @@ -1155,7 +1163,10 @@ Tcl_GlobObjCmd( switch (index) { case GLOB_NOCOMPLAIN: /* -nocomplain */ - globFlags |= TCL_GLOBMODE_NO_COMPLAIN; + /* + * Do nothing; This is normal operations in Tcl 9. + * Keep accepting as a no-op option to accommodate old scripts. + */ break; case GLOB_DIR: /* -dir */ if (i == (objc-1)) { @@ -1513,41 +1524,6 @@ Tcl_GlobObjCmd( } } - if ((globFlags & TCL_GLOBMODE_NO_COMPLAIN) == 0) { - if (TclListObjLengthM(interp, Tcl_GetObjResult(interp), - &length) != TCL_OK) { - /* - * This should never happen. Maybe we should be more dramatic. - */ - - result = TCL_ERROR; - goto endOfGlob; - } - - if (length == 0) { - Tcl_Obj *errorMsg = - Tcl_ObjPrintf("no files matched glob pattern%s \"", - (join || (objc == 1)) ? "" : "s"); - - if (join) { - Tcl_AppendToObj(errorMsg, Tcl_DStringValue(&prefix), -1); - } else { - const char *sep = ""; - - for (i = 0; i < objc; i++) { - Tcl_AppendPrintfToObj(errorMsg, "%s%s", - sep, TclGetString(objv[i])); - sep = " "; - } - } - Tcl_AppendToObj(errorMsg, "\"", -1); - Tcl_SetObjResult(interp, errorMsg); - Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "NOMATCH", - NULL); - result = TCL_ERROR; - } - } - endOfGlob: if (join || (dir == PATH_GENERAL)) { Tcl_DStringFree(&prefix); @@ -1595,7 +1571,7 @@ Tcl_GlobObjCmd( *---------------------------------------------------------------------- */ -int +static int TclGlob( Tcl_Interp *interp, /* Interpreter for returning error message or * appending list of matching file names. */ diff --git a/generic/tclInt.h b/generic/tclInt.h index a02650a..a876f37 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2767,16 +2767,6 @@ typedef struct TclFileAttrProcs { typedef struct TclFile_ *TclFile; -/* - * The "globParameters" argument of the function TclGlob is an or'ed - * combination of the following values: - */ - -#define TCL_GLOBMODE_NO_COMPLAIN 1 -#define TCL_GLOBMODE_JOIN 2 -#define TCL_GLOBMODE_DIR 4 -#define TCL_GLOBMODE_TAILS 8 - typedef enum Tcl_PathPart { TCL_PATH_DIRNAME, TCL_PATH_TAIL, @@ -3188,9 +3178,6 @@ MODULE_SCOPE int TclGetLoadedLibraries(Tcl_Interp *interp, const char *packageName); MODULE_SCOPE int TclGetWideBitsFromObj(Tcl_Interp *, Tcl_Obj *, Tcl_WideInt *); -MODULE_SCOPE int TclGlob(Tcl_Interp *interp, char *pattern, - Tcl_Obj *unquotedPrefix, int globFlags, - Tcl_GlobTypeData *types); MODULE_SCOPE int TclIncrObj(Tcl_Interp *interp, Tcl_Obj *valuePtr, Tcl_Obj *incrPtr); MODULE_SCOPE Tcl_Obj * TclIncrObjVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr, diff --git a/library/package.tcl b/library/package.tcl index 5f0795f..0c4aa29 100644 --- a/library/package.tcl +++ b/library/package.tcl @@ -137,6 +137,9 @@ proc pkg_mkIndex {args} { } on error {msg opt} { return -options $opt $msg } + if {[llength $fileList] == 0} { + return -code error "no files matched glob pattern \"$patternList\"" + } foreach file $fileList { # For each file, figure out what commands and packages it provides. # To do this, create a child interpreter, load the file into the diff --git a/tests/fCmd.test b/tests/fCmd.test index 811beb3..93793d1 100644 --- a/tests/fCmd.test +++ b/tests/fCmd.test @@ -829,12 +829,12 @@ test fCmd-7.4 {FileForceOption: bad option} -constraints {notRoot} -setup { } -result {bad option "-tf1": must be -force or --} test fCmd-7.5 {FileForceOption: multiple times through loop} -setup { cleanup -} -constraints {notRoot} -returnCodes error -body { +} -constraints {notRoot} -body { createfile -- createfile -force file delete -force -force -- -- -force glob -- -- -force -} -result {no files matched glob patterns "-- -force"} +} -result {} test fCmd-8.1 {FileBasename: basename of ~user: argc == 1 && *path == ~} \ -constraints {unix notRoot knownBug tildeexpansion} -body { @@ -994,9 +994,9 @@ test fCmd-9.10 {file rename: comprehensive: file to new name and dir} -setup { testchmod 0o444 tf2 file rename tf1 [file join td1 tf3] file rename tf2 [file join td1 tf4] - list [catch {glob tf*}] [lsort [glob -directory td1 t*]] \ + list [glob tf*] [lsort [glob -directory td1 t*]] \ [file writable [file join td1 tf3]] [file writable [file join td1 tf4]] -} -result [subst {1 {[file join td1 tf3] [file join td1 tf4]} 1 0}] +} -result [subst {{} {[file join td1 tf3] [file join td1 tf4]} 1 0}] test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} -setup { cleanup } -constraints {notRoot testchmod} -body { diff --git a/tests/fileName.test b/tests/fileName.test index c4735cb..416c419 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -701,9 +701,9 @@ test filename-10.24 {Tcl_TranslateFileName} -body { testtranslatefilename ~ouster/foo } -result {/home/ouster/foo} -constraints {nonPortable testtranslatefilename} -test filename-11.1 {Tcl_GlobCmd} -returnCodes error -body { +test filename-11.1 {Tcl_GlobCmd} -body { glob -} -result {no files matched glob patterns ""} +} -result {} test filename-11.2 {Tcl_GlobCmd} -returnCodes error -body { glob -gorp } -result {bad option "-gorp": must be -directory, -join, -nocomplain, -path, -tails, -types, or --} @@ -717,19 +717,19 @@ test filename-11.5 {Tcl_GlobCmd} -body { # Should not error out because of ~ catch {glob -nocomplain * ~xyqrszzz} } -result 0 -test filename-11.6 {Tcl_GlobCmd} -returnCodes error -body { +test filename-11.6 {Tcl_GlobCmd} -body { glob ~xyqrszzz -} -result {no files matched glob pattern "~xyqrszzz"} -test filename-11.7 {Tcl_GlobCmd} -returnCodes error -body { +} -result {} +test filename-11.7 {Tcl_GlobCmd} -body { glob -- -nocomplain -} -result {no files matched glob pattern "-nocomplain"} +} -result {} test filename-11.8 {Tcl_GlobCmd} -body { glob -nocomplain -- -nocomplain } -result {} test filename-11.9 {Tcl_GlobCmd} -constraints {testsetplatform} -body { testsetplatform unix glob ~\\xyqrszzz/bar -} -returnCodes error -result {no files matched glob pattern "~\xyqrszzz/bar"} +} -result {} test filename-11.10 {Tcl_GlobCmd} -constraints {testsetplatform} -body { testsetplatform unix glob -nocomplain ~\\xyqrszzz/bar @@ -737,22 +737,22 @@ test filename-11.10 {Tcl_GlobCmd} -constraints {testsetplatform} -body { test filename-11.11 {Tcl_GlobCmd} -constraints {testsetplatform} -body { testsetplatform unix glob ~xyqrszzz\\/\\bar -} -returnCodes error -result {no files matched glob pattern "~xyqrszzz\/\bar"} +} -result {} test filename-11.12 {Tcl_GlobCmd} -constraints {testsetplatform} -setup { testsetplatform unix set home $env(HOME) } -body { unset env(HOME) glob ~/* -} -returnCodes error -cleanup { +} -cleanup { set env(HOME) $home -} -result {no files matched glob pattern "~/*"} +} -result {} if {[testConstraint testsetplatform]} { testsetplatform $platform } test filename-11.13 {Tcl_GlobCmd} -body { file join [lindex [glob ~] 0] -} -returnCodes error -result {no files matched glob pattern "~"} +} -result {} set oldpwd [pwd] set oldhome $env(HOME) catch {cd [makeDirectory tcl[pid]]} @@ -772,10 +772,10 @@ touch globTest/.1 touch globTest/x,z1.c test filename-11.14 {Tcl_GlobCmd} -body { glob ~/globTest -} -returnCodes error -result {no files matched glob pattern "~/globTest"} +} -result {} test filename-11.15 {Tcl_GlobCmd} -body { glob ~\\/globTest -} -returnCodes error -result {no files matched glob pattern "~\/globTest"} +} -result {} test filename-11.16 {Tcl_GlobCmd} { glob globTest } {globTest} @@ -1098,42 +1098,42 @@ file delete -force $tildeglobname set globname globTest unset horribleglobname tildeglobname -test filename-12.1 {simple globbing} {unixOrWin} { +test filename-12.1 {simple globbing} -constraints {unixOrWin} -body { glob {} -} {.} +} -result {.} test filename-12.1.1 {simple globbing} -constraints {unixOrWin} -body { glob -types f {} -} -returnCodes error -result {no files matched glob pattern ""} -test filename-12.1.2 {simple globbing} {unixOrWin} { +} -result {} +test filename-12.1.2 {simple globbing} -constraints {unixOrWin} -body { glob -types d {} -} {.} -test filename-12.1.3 {simple globbing} {unix} { +} -result {.} +test filename-12.1.3 {simple globbing} -constraints {unix} -body { glob -types hidden {} -} {.} +} -result {.} test filename-12.1.4 {simple globbing} -constraints {win} -body { glob -types hidden {} -} -returnCodes error -result {no files matched glob pattern ""} +} -result {} test filename-12.1.5 {simple globbing} -constraints {win} -body { glob -types hidden c:/ -} -returnCodes error -result {no files matched glob pattern "c:/"} -test filename-12.1.6 {simple globbing} {win} { +} -result {} +test filename-12.1.6 {simple globbing} -constraints {win} -body { glob c:/ -} {c:/} -test filename-12.3 {simple globbing} { +} -result {c:/} +test filename-12.3 {simple globbing} -body { glob -nocomplain \{a1,a2\} -} {} +} -result {} set globPreResult globTest/ set x1 x1.c set y1 y1.c -test filename-12.4 {simple globbing} {unixOrWin} { +test filename-12.4 {simple globbing} -constraints {unixOrWin} -body { lsort [glob globTest/x1.c globTest/y1.c globTest/foo] -} "$globPreResult$x1 $globPreResult$y1" -test filename-12.5 {simple globbing} { +} -result "$globPreResult$x1 $globPreResult$y1" +test filename-12.5 {simple globbing} -body { glob globTest\\/x1.c -} "$globPreResult$x1" -test filename-12.6 {simple globbing} { +} -result "$globPreResult$x1" +test filename-12.6 {simple globbing} -body { glob globTest\\/\\x1.c -} "$globPreResult$x1" +} -result "$globPreResult$x1" test filename-12.7 {globbing at filesystem root} -constraints {unix} -body { list [glob -nocomplain /*] [glob -path / *] } -match compareWords -result equal @@ -1265,10 +1265,10 @@ test filename-14.20 {asterisks, question marks, and brackets} { } {} test filename-14.21 {asterisks, question marks, and brackets} -body { glob globTest/*/gorp -} -returnCodes error -result {no files matched glob pattern "globTest/*/gorp"} +} -result {} test filename-14.22 {asterisks, question marks, and brackets} -body { glob goo/* x*z foo?q -} -returnCodes error -result {no files matched glob patterns "goo/* x*z foo?q"} +} -result {} test filename-14.23 {slash globbing} {unix} { glob / } / @@ -1368,7 +1368,7 @@ test filename-15.5 {unix specific globbing} {unix nonPortable} { # supported, the test was meaningless test filename-15.7 {glob tilde} -body { glob ~ -} -returnCodes error -result {no files matched glob pattern "~"} +} -result {} test filename-15.8 {win and unix specific globbing} -constraints {unixOrWin} -setup { global env set temp $env(HOME) @@ -1379,7 +1379,7 @@ test filename-15.8 {win and unix specific globbing} -constraints {unixOrWin} -se } -cleanup { set env(HOME) $temp catch {file delete -force $env(HOME)/globTest/anyname} -} -returnCodes error -result {no files matched glob pattern "~"} +} -result {} # The following tests are only valid for Windows systems. set oldDir [pwd] diff --git a/tests/winFile.test b/tests/winFile.test index 38f6954..231fb3f 100644 --- a/tests/winFile.test +++ b/tests/winFile.test @@ -28,7 +28,7 @@ testConstraint notWine [expr {![info exists ::env(CI_USING_WINE)]}] test winFile-1.1 {TclpGetUserHome} -constraints {win} -body { glob ~nosuchuser -} -returnCodes error -result {no files matched glob pattern "~nosuchuser"} +} -result {} test winFile-1.2 {TclpGetUserHome} -constraints {win nonPortable} -body { # The administrator account should always exist. glob ~administrator -- cgit v0.12 From 4656afb575cda58ec7b6ce77f0a96b98173ca36d Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Mon, 17 Oct 2022 19:44:08 +0000 Subject: More octal -> hex usage --- doc/Eval.3 | 6 ++-- doc/FileSystem.3 | 6 ++-- doc/Number.3 | 8 ++--- doc/source.n | 4 +-- doc/tclsh.1 | 8 ++--- generic/regc_lex.c | 4 +-- generic/regc_locale.c | 86 +++++++++++++++++++++++++-------------------------- generic/tclObj.c | 6 ++-- library/auto.tcl | 4 +-- library/init.tcl | 2 +- library/safe.tcl | 2 +- tools/genStubs.tcl | 2 +- 12 files changed, 64 insertions(+), 74 deletions(-) diff --git a/doc/Eval.3 b/doc/Eval.3 index 3ae0bce..02a8da5 100644 --- a/doc/Eval.3 +++ b/doc/Eval.3 @@ -99,13 +99,11 @@ its contents as a Tcl script. It returns the same information as If the file could not be read then a Tcl error is returned to describe why the file could not be read. The eofchar for files is -.QW \e32 +.QW \ex1A (^Z) for all platforms. If you require a .QW ^Z in code for string comparison, you can use -.QW \e032 -or -.QW \eu001a , +.QW \ex1A , which will be safely substituted by the Tcl interpreter into .QW ^Z . .PP diff --git a/doc/FileSystem.3 b/doc/FileSystem.3 index 4951ec5..e7cc4ab 100644 --- a/doc/FileSystem.3 +++ b/doc/FileSystem.3 @@ -425,14 +425,12 @@ reading the file contents. If the file could not be read then a Tcl error is returned to describe why the file could not be read. The eofchar for files is -.QW \e32 +.QW \ex1A (^Z) for all platforms. If you require a .QW ^Z in code for string comparison, you can use -.QW \e032 -or -.QW \eu001a , +.QW \ex1A , which will be safely substituted by the Tcl interpreter into .QW ^Z . \fBTcl_FSEvalFile\fR is a simpler version of diff --git a/doc/Number.3 b/doc/Number.3 index f93d75d..f405060 100644 --- a/doc/Number.3 +++ b/doc/Number.3 @@ -50,7 +50,7 @@ Tcl recognizes many values as numbers. Several examples include: \fB"1_000_000"\fR, \fB"4.0"\fR, \fB"1e-7"\fR, \fB"NaN"\fR, or \fB"Inf"\fR. When built-in Tcl commands act on these values as numbers, they are converted to a numeric representation for efficient handling in C code. Tcl makes -use of three C types to store these representations: \fBdouble\fR, +use of three C types to store these representations: \fBdouble\fR, \fBTcl_WideInt\fR, and \fBmp_int\fR. The \fBdouble\fR type is provided by the C language standard. The \fBTcl_WideInt\fR type is declared in the Tcl header file, \fBtcl.h\fR, and is equivalent to the C standard type @@ -76,7 +76,7 @@ If Tcl does recognize the examined value as a number, both routines return and \fItypePtr\fR (which may not be NULL) to report information the caller can use to retrieve the numeric representation. Both routines write to *\fIclientDataPtr\fR a pointer to the internal storage location -where Tcl holds the converted numeric value. +where Tcl holds the converted numeric value. .PP When the converted numeric value is stored as a \fBdouble\fR, a call to math library routine \fBisnan\fR determines whether that @@ -91,13 +91,13 @@ the \fBdouble\fR numeric value may be read through it. .PP When the converted numeric value is stored as a \fBTcl_WideInt\fR, both \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR write the -value \fBTCL_NUMBER_INT\fR to *\fItypePtr\fR. +value \fBTCL_NUMBER_INT\fR to *\fItypePtr\fR. The storage pointer may be cast to type \fBconst Tcl_WideInt *\fR and the \fBTcl_WideInt\fR numeric value may be read through it. .PP When the converted numeric value is stored as an \fBmp_int\fR, both \fBTcl_GetNumber\fR and \fBTcl_GetNumberFromObj\fR write the -value \fBTCL_NUMBER_BIG\fR to *\fItypePtr\fR. +value \fBTCL_NUMBER_BIG\fR to *\fItypePtr\fR. The storage pointer may be cast to type \fBconst mp_int *\fR and the \fBmp_int\fR numeric value may be read through it. .PP diff --git a/doc/source.n b/doc/source.n index 8757cb8..cee1312 100644 --- a/doc/source.n +++ b/doc/source.n @@ -37,9 +37,7 @@ allowing for files containing code and data segments (scripted documents). If you require a .QW ^Z in code for string comparison, you can use -.QW \e032 -or -.QW \eu001a , +.QW \ex1A , which will be safely substituted by the Tcl interpreter into .QW ^Z . .PP diff --git a/doc/tclsh.1 b/doc/tclsh.1 index 8dbacc0..3a78737 100644 --- a/doc/tclsh.1 +++ b/doc/tclsh.1 @@ -38,15 +38,11 @@ read Tcl commands from the named file; \fBtclsh\fR will exit when it reaches the end of the file. The end of the file may be marked either by the physical end of the medium, or by the character, -.QW \e032 -.PQ \eu001a ", control-Z" . +.PQ \ex1A ", control-Z" . If this character is present in the file, the \fBtclsh\fR application will read text up to but not including the character. An application that requires this character in the file may safely encode it as -.QW \e032 , -.QW \ex1A , -or -.QW \eu001a ; +.QW \ex1A ; or may generate it by use of commands such as \fBformat\fR or \fBbinary\fR. There is no automatic evaluation of \fB.tclshrc\fR when the name of a script file is presented on the \fBtclsh\fR command diff --git a/generic/regc_lex.c b/generic/regc_lex.c index bad91ce..eb068b4 100644 --- a/generic/regc_lex.c +++ b/generic/regc_lex.c @@ -775,7 +775,7 @@ lexescape( NOTE(REG_UNONPOSIX); switch (c) { case CHR('a'): - RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007'))); + RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\x07'))); break; case CHR('A'): RETV(SBEGIN, 0); @@ -803,7 +803,7 @@ lexescape( break; case CHR('e'): NOTE(REG_UUNPORT); - RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\033'))); + RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\x1B'))); break; case CHR('f'): RETV(PLAIN, CHR('\f')); diff --git a/generic/regc_locale.c b/generic/regc_locale.c index e74b147..1ac04ef 100644 --- a/generic/regc_locale.c +++ b/generic/regc_locale.c @@ -16,49 +16,49 @@ static const struct cname { const char *name; const char code; } cnames[] = { - {"NUL", '\0'}, - {"SOH", '\001'}, - {"STX", '\002'}, - {"ETX", '\003'}, - {"EOT", '\004'}, - {"ENQ", '\005'}, - {"ACK", '\006'}, - {"BEL", '\007'}, - {"alert", '\007'}, - {"BS", '\010'}, - {"backspace", '\b'}, - {"HT", '\011'}, - {"tab", '\t'}, - {"LF", '\012'}, - {"newline", '\n'}, - {"VT", '\013'}, - {"vertical-tab", '\v'}, - {"FF", '\014'}, - {"form-feed", '\f'}, - {"CR", '\015'}, - {"carriage-return", '\r'}, - {"SO", '\016'}, - {"SI", '\017'}, - {"DLE", '\020'}, - {"DC1", '\021'}, - {"DC2", '\022'}, - {"DC3", '\023'}, - {"DC4", '\024'}, - {"NAK", '\025'}, - {"SYN", '\026'}, - {"ETB", '\027'}, - {"CAN", '\030'}, - {"EM", '\031'}, - {"SUB", '\032'}, - {"ESC", '\033'}, - {"IS4", '\034'}, - {"FS", '\034'}, - {"IS3", '\035'}, - {"GS", '\035'}, - {"IS2", '\036'}, - {"RS", '\036'}, - {"IS1", '\037'}, - {"US", '\037'}, + {"NUL", '\x00'}, + {"SOH", '\x01'}, + {"STX", '\x02'}, + {"ETX", '\x03'}, + {"EOT", '\x04'}, + {"ENQ", '\x05'}, + {"ACK", '\x06'}, + {"BEL", '\x07'}, + {"alert", '\x07'}, + {"BS", '\x08'}, + {"backspace", '\x08'}, + {"HT", '\x09'}, + {"tab", '\x09'}, + {"LF", '\x0A'}, + {"newline", '\x0A'}, + {"VT", '\x0B'}, + {"vertical-tab", '\x0B'}, + {"FF", '\x0C'}, + {"form-feed", '\x0C'}, + {"CR", '\x0D'}, + {"carriage-return", '\x0D'}, + {"SO", '\x0E'}, + {"SI", '\x0F'}, + {"DLE", '\x10'}, + {"DC1", '\x11'}, + {"DC2", '\x12'}, + {"DC3", '\x13'}, + {"DC4", '\x14'}, + {"NAK", '\x15'}, + {"SYN", '\x16'}, + {"ETB", '\x17'}, + {"CAN", '\x18'}, + {"EM", '\x19'}, + {"SUB", '\x1A'}, + {"ESC", '\x1B'}, + {"IS4", '\x1C'}, + {"FS", '\x1C'}, + {"IS3", '\x1D'}, + {"GS", '\x1D'}, + {"IS2", '\x1E'}, + {"RS", '\x1E'}, + {"IS1", '\x1F'}, + {"US", '\x1F'}, {"space", ' '}, {"exclamation-mark",'!'}, {"quotation-mark", '"'}, diff --git a/generic/tclObj.c b/generic/tclObj.c index 8970ab0..4a660b2 100644 --- a/generic/tclObj.c +++ b/generic/tclObj.c @@ -785,7 +785,7 @@ TclContinuationsGet( static void TclThreadFinalizeContLines( - TCL_UNUSED(ClientData)) + TCL_UNUSED(void *)) { /* * Release the hashtable tracking invisible continuation lines. @@ -3956,7 +3956,7 @@ Tcl_GetNumber( Tcl_Interp *interp, const char *bytes, size_t numBytes, - ClientData *clientDataPtr, + void **clientDataPtr, int *typePtr) { static Tcl_ThreadDataKey numberCacheKey; @@ -4851,7 +4851,7 @@ SetCmdNameFromAny( int Tcl_RepresentationCmd( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) diff --git a/library/auto.tcl b/library/auto.tcl index dc37328..3b1bb05 100644 --- a/library/auto.tcl +++ b/library/auto.tcl @@ -302,7 +302,7 @@ proc auto_mkindex_old {dir args} { set f "" set error [catch { set f [open $file] - fconfigure $f -encoding utf-8 -eofchar "\032 {}" + fconfigure $f -encoding utf-8 -eofchar "\x1A {}" while {[gets $f line] >= 0} { if {[regexp {^proc[ ]+([^ ]*)} $line match procName]} { set procName [lindex [auto_qualify $procName "::"] 0] @@ -414,7 +414,7 @@ proc auto_mkindex_parser::mkindex {file} { set scriptFile $file set fid [open $file] - fconfigure $fid -encoding utf-8 -eofchar "\032 {}" + fconfigure $fid -encoding utf-8 -eofchar "\x1A {}" set contents [read $fid] close $fid diff --git a/library/init.tcl b/library/init.tcl index a879fe5..bbff158 100644 --- a/library/init.tcl +++ b/library/init.tcl @@ -442,7 +442,7 @@ proc auto_load_index {} { continue } else { set error [catch { - fconfigure $f -encoding utf-8 -eofchar "\032 {}" + fconfigure $f -encoding utf-8 -eofchar "\x1A {}" set id [gets $f] if {$id eq "# Tcl autoload index file, version 2.0"} { eval [read $f] diff --git a/library/safe.tcl b/library/safe.tcl index 2e04f8e..9050880 100644 --- a/library/safe.tcl +++ b/library/safe.tcl @@ -980,7 +980,7 @@ proc ::safe::AliasSource {child args} { set replacementMsg "script error" set code [catch { set f [open $realfile] - fconfigure $f -encoding $encoding -eofchar "\032 {}" + fconfigure $f -encoding $encoding -eofchar "\x1A {}" set contents [read $f] close $f ::interp eval $child [list info script $file] diff --git a/tools/genStubs.tcl b/tools/genStubs.tcl index 282abcc..89e4ccc 100644 --- a/tools/genStubs.tcl +++ b/tools/genStubs.tcl @@ -257,7 +257,7 @@ proc genStubs::rewriteFile {file text} { return } set in [open ${file} r] - fconfigure $in -eofchar "\032 {}" -encoding utf-8 + fconfigure $in -eofchar "\x1A {}" -encoding utf-8 set out [open ${file}.new w] fconfigure $out -translation lf -encoding utf-8 -- cgit v0.12