summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2022-02-02 16:53:06 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2022-02-02 16:53:06 (GMT)
commit6e51a643257c04e64fcd6684e45d068705d9587f (patch)
tree31d0e9d94636098e2e1cb080903710d75a44d4c5
parentbb38bb643d51cb226998de0ceb24ec6dec3633a7 (diff)
parentfd9dbdd294fbd96680bd4235087d418bc1cd6935 (diff)
downloadtcl-6e51a643257c04e64fcd6684e45d068705d9587f.zip
tcl-6e51a643257c04e64fcd6684e45d068705d9587f.tar.gz
tcl-6e51a643257c04e64fcd6684e45d068705d9587f.tar.bz2
Merge 8.7
-rw-r--r--doc/expr.n137
-rw-r--r--generic/tclMain.c39
-rw-r--r--unix/tclAppInit.c4
-rw-r--r--win/tclAppInit.c9
4 files changed, 98 insertions, 91 deletions
diff --git a/doc/expr.n b/doc/expr.n
index 43ad26f..490217c 100644
--- a/doc/expr.n
+++ b/doc/expr.n
@@ -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