Compare commits

...
Author SHA1 Message Date
dkf bcca980f06 Add [dict getdef] alias 2019-04-15 19:57:54 +00:00
dgp 6ae823b6b7 merge 8.7 2019-04-12 19:44:34 +00:00
dkf 325bbf5792 Document 2019-04-01 10:51:33 +00:00
dkf 8d4509eafc Add tests 2019-04-01 10:38:47 +00:00
dkf d2fb211d20 Implement [dict getwithdefault] 2019-04-01 08:48:16 +00:00
5 changed files with 141 additions and 0 deletions
+16
View File
@@ -120,6 +120,22 @@ It is an error to attempt to retrieve a value for a key that is not
present in the dictionary.
.RE
.TP
\fBdict getdef \fIdictionaryValue \fR?\fIkey ...\fR? \fIkey default\fR
.TP
\fBdict getwithdefault \fIdictionaryValue \fR?\fIkey ...\fR? \fIkey default\fR
.VS "8.7, TIP342"
This behaves the same as \fBdict get\fR (with at least one \fIkey\fR
argument), returning the value that the key path maps to in the
dictionary \fIdictionaryValue\fR, except that instead of producing an
error because the \fIkey\fR (or one of the \fIkey\fRs on the key path)
is absent, it returns the \fIdefault\fR argument instead.
.RS
.PP
Note that there must always be at least one \fIkey\fR provided, and that
\fBdict getdef\fR and \fBdict getwithdefault\fR are aliases for each other.
.RE
.VE "8.7, TIP342"
.TP
\fBdict incr \fIdictionaryVariable key \fR?\fIincrement\fR?
.
This adds the given increment value (an integer that defaults to 1 if
+69
View File
@@ -34,6 +34,8 @@ static int DictFilterCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
static int DictGetCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
static int DictGetDefCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
static int DictIncrCmd(ClientData dummy, Tcl_Interp *interp,
int objc, Tcl_Obj *const *objv);
static int DictInfoCmd(ClientData dummy, Tcl_Interp *interp,
@@ -89,6 +91,8 @@ static const EnsembleImplMap implementationMap[] = {
{"filter", DictFilterCmd, NULL, NULL, NULL, 0 },
{"for", NULL, TclCompileDictForCmd, DictForNRCmd, NULL, 0 },
{"get", DictGetCmd, TclCompileDictGetCmd, NULL, NULL, 0 },
{"getdef", DictGetDefCmd, NULL, NULL, NULL, 0 },
{"getwithdefault", DictGetDefCmd, NULL, NULL, NULL, 0 },
{"incr", DictIncrCmd, TclCompileDictIncrCmd, NULL, NULL, 0 },
{"info", DictInfoCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
{"keys", DictKeysCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
@@ -1624,6 +1628,71 @@ DictGetCmd(
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
* DictGetDefCmd --
*
* This function implements the "dict getdef" and "dict getwithdefault"
* Tcl commands. See the user documentation for details on what it does,
* and TIP#342 for the formal specification.
*
* Results:
* A standard Tcl result.
*
* Side effects:
* See the user documentation.
*
*----------------------------------------------------------------------
*/
static int
DictGetDefCmd(
ClientData dummy,
Tcl_Interp *interp,
int objc,
Tcl_Obj *const *objv)
{
Tcl_Obj *dictPtr, *keyPtr, *valuePtr, *defaultPtr;
Tcl_Obj *const *keyPath;
int numKeys;
if (objc < 4) {
Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key ...? key default");
return TCL_ERROR;
}
/*
* Give the bits of arguments names for clarity.
*/
dictPtr = objv[1];
keyPath = &objv[2];
numKeys = objc - 4; /* Number of keys in keyPath; there's always
* one extra key afterwards too. */
keyPtr = objv[objc - 2];
defaultPtr = objv[objc - 1];
/*
* Implement the getting-with-default operation.
*/
dictPtr = TclTraceDictPath(interp, dictPtr, numKeys, keyPath,
DICT_PATH_EXISTS);
if (dictPtr == NULL) {
return TCL_ERROR;
} else if (dictPtr == DICT_PATH_NON_EXISTENT) {
Tcl_SetObjResult(interp, defaultPtr);
} else if (Tcl_DictObjGet(interp, dictPtr, keyPtr, &valuePtr) != TCL_OK) {
return TCL_ERROR;
} else if (valuePtr == NULL) {
Tcl_SetObjResult(interp, defaultPtr);
} else {
Tcl_SetObjResult(interp, valuePtr);
}
return TCL_OK;
}
/*
*----------------------------------------------------------------------
*
+56
View File
@@ -2047,6 +2047,62 @@ test dict-25.1 {compiled dict update with low-refcount values [Bug d553228d9f]}
dict update item item item two two {}
}}
} {}
test dict-26.1 {dict getdef command} -body {
dict getdef {a b} a c
} -result b
test dict-26.2 {dict getdef command} -body {
dict getdef {a b} b c
} -result c
test dict-26.3 {dict getdef command} -body {
dict getdef {a {b c}} a b d
} -result c
test dict-26.4 {dict getdef command} -body {
dict getdef {a {b c}} a c d
} -result d
test dict-26.5 {dict getdef command} -body {
dict getdef {a {b c}} b c d
} -result d
test dict-26.6 {dict getdef command} -returnCodes error -body {
dict getdef {a {b c d}} a b d
} -result {missing value to go with key}
test dict-26.7 {dict getdef command} -returnCodes error -body {
dict getdef
} -result {wrong # args: should be "dict getdef dictionary ?key ...? key default"}
test dict-26.8 {dict getdef command} -returnCodes error -body {
dict getdef {}
} -result {wrong # args: should be "dict getdef dictionary ?key ...? key default"}
test dict-26.9 {dict getdef command} -returnCodes error -body {
dict getdef {} {}
} -result {wrong # args: should be "dict getdef dictionary ?key ...? key default"}
test dict-27.1 {dict getwithdefault command} -body {
dict getwithdefault {a b} a c
} -result b
test dict-27.2 {dict getwithdefault command} -body {
dict getwithdefault {a b} b c
} -result c
test dict-27.3 {dict getwithdefault command} -body {
dict getwithdefault {a {b c}} a b d
} -result c
test dict-27.4 {dict getwithdefault command} -body {
dict getwithdefault {a {b c}} a c d
} -result d
test dict-27.5 {dict getwithdefault command} -body {
dict getwithdefault {a {b c}} b c d
} -result d
test dict-27.6 {dict getwithdefault command} -returnCodes error -body {
dict getwithdefault {a {b c d}} a b d
} -result {missing value to go with key}
test dict-27.7 {dict getwithdefault command} -returnCodes error -body {
dict getwithdefault
} -result {wrong # args: should be "dict getwithdefault dictionary ?key ...? key default"}
test dict-27.8 {dict getwithdefault command} -returnCodes error -body {
dict getwithdefault {}
} -result {wrong # args: should be "dict getwithdefault dictionary ?key ...? key default"}
test dict-27.9 {dict getwithdefault command} -returnCodes error -body {
dict getwithdefault {} {}
} -result {wrong # args: should be "dict getwithdefault dictionary ?key ...? key default"}
# cleanup
::tcltest::cleanupTests
Regular → Executable
View File
Regular → Executable
View File