diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-02-02 16:53:06 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2022-02-02 16:53:06 (GMT) |
| commit | 6e51a643257c04e64fcd6684e45d068705d9587f (patch) | |
| tree | 31d0e9d94636098e2e1cb080903710d75a44d4c5 | |
| parent | bb38bb643d51cb226998de0ceb24ec6dec3633a7 (diff) | |
| parent | fd9dbdd294fbd96680bd4235087d418bc1cd6935 (diff) | |
| download | tcl-6e51a643257c04e64fcd6684e45d068705d9587f.zip tcl-6e51a643257c04e64fcd6684e45d068705d9587f.tar.gz tcl-6e51a643257c04e64fcd6684e45d068705d9587f.tar.bz2 | |
Merge 8.7
| -rw-r--r-- | doc/expr.n | 137 | ||||
| -rw-r--r-- | generic/tclMain.c | 39 | ||||
| -rw-r--r-- | unix/tclAppInit.c | 4 | ||||
| -rw-r--r-- | win/tclAppInit.c | 9 |
4 files changed, 98 insertions, 91 deletions
@@ -17,7 +17,7 @@ expr \- Evaluate an expression .BE .SH DESCRIPTION .PP -The \fIexpr\fR command concatenates \fIarg\fRs, separated by a space, into an expression, and evaluates +Concatenates \fIarg\fRs, separated by a space, into an expression, and evaluates that expression, returning its value. The operators permitted in an expression include a subset of the operators permitted in C expressions. For those operators @@ -37,76 +37,36 @@ operands are specified. Expressions also support non-numeric operands, string comparisons, and some additional operators not found in C. .PP -When an expression evaluates to an integer, the value is the decimal form of -the integer, and when an expression evaluates to a floating-point number, the -value is the form produced by the \fB%g\fR format specifier of Tcl's -\fBformat\fR command. +When the result of expression is an integer, it is in decimal form, and when +the result is a floating-point number, it is in the form produced by the +\fB%g\fR format specifier of \fBformat\fR. .PP .VS "TIP 582" -You can use \fB#\fR at any point in the expression (except inside double -quotes or braces) to start a comment. Comments last to the end of the line or +At any point in the expression except within double quotes or braces, \fB#\fR +is the beginning of a comment, which lasts to the end of the line or the end of the expression, whichever comes first. .VE "TIP 582" .SS OPERANDS .PP An expression consists of a combination of operands, operators, parentheses and commas, possibly with whitespace between any of these elements, which is -ignored. +ignored. Each operand is intepreted as a numeric value if at all possible. .PP -An operand may be specified in any of the following ways: -.IP [1] -As a numeric value, either integer or floating-point. -.IP [2] -As a boolean value, using any form understood by \fBstring is\fR -\fBboolean\fR. -.IP [3] -As a variable, using standard \fB$\fR notation. -The value of the variable is then the value of the operand. -.IP [4] -As a string enclosed in double-quotes. -Backslash, variable, and command substitution are performed as described in -\fBTcl\fR. -.IP [5] -As a string enclosed in braces. -The operand is treated as a braced value as described in \fBTcl\fR. -.IP [6] -As a Tcl command enclosed in brackets. -Command substitution is performed as described in \fBTcl\fR. -.IP [7] -As a mathematical function such as \fBsin($x)\fR, whose arguments have any of the above -forms for operands. See \fBMATH FUNCTIONS\fR below for -a discussion of how mathematical functions are handled. -.PP -Because \fBexpr\fR parses and performs substitutions on values that have -already been parsed and substituted by \fBTcl\fR, it is usually best to enclose -expressions in braces to avoid the first round of substitutions by -\fBTcl\fR. -.PP -Below are some examples of simple expressions where the value of \fBa\fR is 3 -and the value of \fBb\fR is 6. The command on the left side of each line -produces the value on the right side. -.PP -.CS -.ta 9c -\fBexpr\fR {3.1 + $a} \fI6.1\fR -\fBexpr\fR {2 + "$a.$b"} \fI5.6\fR -\fBexpr\fR {4*[llength "6 2"]} \fI8\fR -\fBexpr\fR {{word one} < "word $a"} \fI0\fR -.CE -.PP -\fBInteger value\fR +Each operand has one of the following forms: +.RS .PP -An integer operand may be specified in decimal (the normal case, the optional -first two characters are \fB0d\fR), binary -(the first two characters are \fB0b\fR), octal -(the first two characters are \fB0o\fR), or hexadecimal -(the first two characters are \fB0x\fR) form. For -compatibility with older Tcl releases, an operand that begins with \fB0\fR is -interpreted as an octal integer even if the second character is not \fBo\fR. +.TP +A \fBnumeric value\fR .PP -\fBFloating-point value\fR +.RS +. +Either integer or floating-point. The first two characters of an integer may +also be \fB0d\fR for decimal, \fB0b\fR for binary, \fB0o\fR for octal or +\fB0x\fR for hexadicimal. For compatibility with older Tcl releases, an +operand that begins with \fB0\fR is interpreted as an octal integer even if the +second character is not \fBo\fR. .PP -A floating-point number may be specified in any of several +A floating-point number may be take any of several common decimal formats, and may use the decimal point \fB.\fR, \fBe\fR or \fBE\fR for scientific notation, and the sign characters \fB+\fR and \fB\-\fR. The @@ -116,16 +76,9 @@ and \fBNaN\fR, in any combination of case, are also recognized as floating point values. An operand that doesn't have a numeric interpretation must be quoted with either braces or with double quotes. .PP -\fBBoolean value\fR -.PP -A boolean value may be represented by any of the values \fB0\fR, \fBfalse\fR, \fBno\fR, -or \fBoff\fR and any of the values \fB1\fR, \fBtrue\fR, \fByes\fR, or \fBon\fR. -.PP -\fBDigit Separator\fR -.PP Digits in any numeric value may be separated with one or more underscore -characters, "\fB_\fR", to improve readability. These separators may only -appear between digits. The separator may not appear at the start of a +characters, "\fB_\fR". A separator may only +appear between digits, not appear at the start of a numeric value, between the leading 0 and radix specifier, or at the end of a numeric value. Here are some examples: .PP @@ -135,6 +88,54 @@ end of a numeric value. Here are some examples: \fBexpr\fR 0xffff_ffff \fI4294967295\fR \fBformat\fR 0x%x 0b1111_1110_1101_1011 \fI0xfedb\fR .CE +.RE + +.TP +A \fBboolean value\fR +. +Using any form understood by \fBstring is\fR +\fBboolean\fR. +.TP +A \fBvariable\fR +. +Using standard \fB$\fR notation. +The value of the variable is the value of the operand. +.TP +A string enclosed in \fBdouble-quotes\fR +. +Backslash, variable, and command substitution are performed according to the +rules for \fBTcl\fR. +.TP +A string enclosed in \fBbraces\fR. +The operand is treated as a braced value according to the rule for braces in +\fBTcl\fR. +.TP +A Tcl command enclosed in \fBbrackets\fR +. +Command substitution is performed as according to the command substitution rule +for \fBTcl\fR. +.TP +A mathematical function such as \fBsin($x)\fR, whose arguments have any of the above +forms for operands. See \fBMATH FUNCTIONS\fR below for +a discussion of how mathematical functions are handled. +.RE +.PP +Because \fBexpr\fR parses and performs substitutions on values that have +already been parsed and substituted by \fBTcl\fR, it is usually best to enclose +expressions in braces to avoid the first round of substitutions by +\fBTcl\fR. +.PP +Below are some examples of simple expressions where the value of \fBa\fR is 3 +and the value of \fBb\fR is 6. The command on the left side of each line +produces the value on the right side. +.PP +.CS +.ta 9c +\fBexpr\fR {3.1 + $a} \fI6.1\fR +\fBexpr\fR {2 + "$a.$b"} \fI5.6\fR +\fBexpr\fR {4*[llength {6 2}]} \fI8\fR +\fBexpr\fR {{word one} < "word $a"} \fI0\fR +.CE .PP .SS OPERATORS .PP diff --git a/generic/tclMain.c b/generic/tclMain.c index bb48dbb..5083383 100644 --- a/generic/tclMain.c +++ b/generic/tclMain.c @@ -28,7 +28,7 @@ * The default prompt used when the user has not overridden it. */ -#define DEFAULT_PRIMARY_PROMPT "% " +static const char DEFAULT_PRIMARY_PROMPT[] = "% "; /* * This file can be compiled on Windows in UNICODE mode, as well as on all @@ -43,7 +43,7 @@ # define _tcscmp strcmp #endif -static Tcl_Obj * +static inline Tcl_Obj * NewNativeObj( TCHAR *string) { @@ -288,6 +288,7 @@ Tcl_MainEx( * but before starting to execute commands. */ Tcl_Interp *interp) { + int i=0; /* argv[i] index */ Tcl_Obj *path, *resultPtr, *argvPtr, *appName; const char *encodingName = NULL; int code, exitCode = 0; @@ -296,7 +297,13 @@ Tcl_MainEx( InteractiveState is; TclpSetInitialEncodings(); - TclpFindExecutable((const char *)argv[0]); + if (0 < argc) { + --argc; /* "consume" argv[0] */ + ++i; + } + TclpFindExecutable ((const char *)argv [0]); /* nb: this could be NULL + * w/ (eg) an empty argv + * supplied to execve() */ Tcl_InitMemory(interp); @@ -318,18 +325,19 @@ Tcl_MainEx( * FILENAME */ - if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) + /* mind argc is being adjusted as we proceed */ + if ((argc >= 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1])) && ('-' != argv[3][0])) { Tcl_Obj *value = NewNativeObj(argv[2]); Tcl_SetStartupScript(NewNativeObj(argv[3]), Tcl_GetString(value)); Tcl_DecrRefCount(value); argc -= 3; - argv += 3; - } else if ((argc > 1) && ('-' != argv[1][0])) { + i += 3; + } else if ((argc >= 1) && ('-' != argv[1][0])) { Tcl_SetStartupScript(NewNativeObj(argv[1]), NULL); argc--; - argv++; + i++; } } @@ -340,14 +348,12 @@ Tcl_MainEx( appName = path; } Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY); - argc--; - argv++; Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewWideIntObj(argc), TCL_GLOBAL_ONLY); argvPtr = Tcl_NewListObj(0, NULL); while (argc--) { - Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++)); + Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(argv[i++])); } Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY); @@ -511,7 +517,7 @@ Tcl_MainEx( * error messages troubles deeper in, so lop it back off. */ - TclGetStringFromObj(is.commandPtr, &length); + (void)Tcl_GetStringFromObj(is.commandPtr, &length); Tcl_SetObjLength(is.commandPtr, --length); code = Tcl_RecordAndEvalObj(interp, is.commandPtr, TCL_EVAL_GLOBAL); @@ -528,7 +534,7 @@ Tcl_MainEx( } else if (is.tty) { resultPtr = Tcl_GetObjResult(interp); Tcl_IncrRefCount(resultPtr); - TclGetStringFromObj(resultPtr, &length); + (void)Tcl_GetStringFromObj(resultPtr, &length); chan = Tcl_GetStdChannel(TCL_STDOUT); if ((length > 0) && chan) { Tcl_WriteObj(chan, resultPtr); @@ -731,7 +737,8 @@ StdinProc( ClientData clientData, /* The state of interactive cmd line */ TCL_UNUSED(int) /*mask*/) { - int code, length; + int code; + int length; InteractiveState *isPtr = (InteractiveState *)clientData; Tcl_Channel chan = isPtr->input; Tcl_Obj *commandPtr = isPtr->commandPtr; @@ -771,7 +778,7 @@ StdinProc( goto prompt; } isPtr->prompt = PROMPT_START; - TclGetStringFromObj(commandPtr, &length); + (void)Tcl_GetStringFromObj(commandPtr, &length); Tcl_SetObjLength(commandPtr, --length); /* @@ -803,7 +810,7 @@ StdinProc( chan = Tcl_GetStdChannel(TCL_STDOUT); Tcl_IncrRefCount(resultPtr); - TclGetStringFromObj(resultPtr, &length); + (void)Tcl_GetStringFromObj(resultPtr, &length); if ((length > 0) && (chan != NULL)) { Tcl_WriteObj(chan, resultPtr); Tcl_WriteChars(chan, "\n", 1); @@ -866,7 +873,7 @@ Prompt( chan = Tcl_GetStdChannel(TCL_STDOUT); if (chan != NULL) { Tcl_WriteChars(chan, DEFAULT_PRIMARY_PROMPT, - strlen(DEFAULT_PRIMARY_PROMPT)); + sizeof(DEFAULT_PRIMARY_PROMPT) - 1); } } } else { diff --git a/unix/tclAppInit.c b/unix/tclAppInit.c index f3caae7..552f9e4 100644 --- a/unix/tclAppInit.c +++ b/unix/tclAppInit.c @@ -83,8 +83,8 @@ main( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#elif !defined(_WIN32) || defined(UNICODE) - /* This doesn't work on Windows without UNICODE */ +#elif (TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 6) && (!defined(_WIN32) || defined(UNICODE)) + /* New in Tcl 8.7. This doesn't work on Windows without UNICODE */ TclZipfs_AppHook(&argc, &argv); #endif diff --git a/win/tclAppInit.c b/win/tclAppInit.c index a10f8db..be70492 100644 --- a/win/tclAppInit.c +++ b/win/tclAppInit.c @@ -91,18 +91,17 @@ MODULE_SCOPE int TCL_LOCAL_MAIN_HOOK(int *argc, TCHAR ***argv); int main( int argc, /* Number of command-line arguments. */ - char **argv1) + char **argv1) /* Not used. */ { TCHAR **argv; - TCHAR *p; #else int _tmain( int argc, /* Number of command-line arguments. */ TCHAR *argv[]) /* Values of command-line arguments. */ { - TCHAR *p; #endif + TCHAR *p; /* * Set up the default locale to be standard "C" locale so parsing is @@ -132,8 +131,8 @@ _tmain( #ifdef TCL_LOCAL_MAIN_HOOK TCL_LOCAL_MAIN_HOOK(&argc, &argv); -#elif !defined(_WIN32) || defined(UNICODE) - /* This doesn't work on Windows without UNICODE */ +#elif (TCL_MAJOR_VERSION > 8 || TCL_MINOR_VERSION > 6) && (!defined(_WIN32) || defined(UNICODE)) + /* New in Tcl 8.7. This doesn't work on Windows without UNICODE */ TclZipfs_AppHook(&argc, &argv); #endif |
