diff options
Diffstat (limited to 'generic/tclDictObj.c')
-rw-r--r-- | generic/tclDictObj.c | 78 |
1 files changed, 73 insertions, 5 deletions
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c index 6bdbfa6..84e8ed4 100644 --- a/generic/tclDictObj.c +++ b/generic/tclDictObj.c @@ -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,9 @@ static const EnsembleImplMap implementationMap[] = { {"filter", DictFilterCmd, NULL, NULL, NULL, 0 }, {"for", NULL, TclCompileDictForCmd, DictForNRCmd, NULL, 0 }, {"get", DictGetCmd, TclCompileDictGetCmd, NULL, NULL, 0 }, + {"getdef", DictGetDefCmd, TclCompileDictGetWithDefaultCmd, NULL,NULL,0}, + {"getwithdefault", DictGetDefCmd, TclCompileDictGetWithDefaultCmd, + NULL, NULL, 0 }, {"incr", DictIncrCmd, TclCompileDictIncrCmd, NULL, NULL, 0 }, {"info", DictInfoCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0 }, {"keys", DictKeysCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 }, @@ -1618,6 +1623,71 @@ DictGetCmd( /* *---------------------------------------------------------------------- * + * 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; +} + +/* + *---------------------------------------------------------------------- + * * DictReplaceCmd -- * * This function implements the "dict replace" Tcl command. See the user @@ -2007,11 +2077,9 @@ DictExistsCmd( return TCL_ERROR; } - dictPtr = TclTraceDictPath(interp, objv[1], objc-3, objv+2, - DICT_PATH_EXISTS); - if (dictPtr == NULL || dictPtr == DICT_PATH_NON_EXISTENT - || Tcl_DictObjGet(interp, dictPtr, objv[objc-1], - &valuePtr) != TCL_OK) { + dictPtr = TclTraceDictPath(NULL, objv[1], objc-3, objv+2,DICT_PATH_EXISTS); + if (dictPtr == NULL || dictPtr == DICT_PATH_NON_EXISTENT || + Tcl_DictObjGet(NULL, dictPtr, objv[objc-1], &valuePtr) != TCL_OK) { Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0)); } else { Tcl_SetObjResult(interp, Tcl_NewBooleanObj(valuePtr != NULL)); |