struct t_hashtable * weechat_tcl_dict_to_hashtable (Tcl_Interp *interp, Tcl_Obj *dict, int hashtable_size) { struct t_hashtable *hashtable; Tcl_DictSearch search; Tcl_Obj *key, *value; int done; hashtable = weechat_hashtable_new (hashtable_size, WEECHAT_HASHTABLE_STRING, WEECHAT_HASHTABLE_STRING, NULL, NULL); if (!hashtable) return NULL; if (Tcl_DictObjFirst (interp, dict, &search, &key, &value, &done) == TCL_OK) { for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) { weechat_hashtable_set (hashtable, Tcl_GetString (key), Tcl_GetString (value)); } } Tcl_DictObjDone(&search); return hashtable; }
/* * Process worker keyword arguments. * Only modifies arguments if the keyword arg was encountered, i.e. * caller should initialise the arguments to their default values. * * This will validate any values received. */ static int worker_keyword_args(Tcl_Interp *interp, Tcl_Obj *const objv[], Tcl_Obj *dict, int *buffer_count, int *buffer_size) { int rc; Tcl_DictSearch search; Tcl_Obj *key_obj, *val_obj; int done; rc = Tcl_DictObjFirst(interp, dict, &search, &key_obj, &val_obj, &done); TCL_CHECK_MSG(rc, "Error iterating over dict: %s", Tcl_GetString(dict)); for (; !done; Tcl_DictObjNext(&search, &key_obj, &val_obj, &done)) { const char *key = Tcl_GetString(key_obj); if (strcmp(key, "buffer_count") == 0) { rc = Tcl_GetIntFromObj(interp, val_obj, buffer_count); TCL_CHECK_MSG(rc, "Expected integer value for buffer_count"); TCL_CONDITION(*buffer_count >= 0, "Positive value for " "buffer_count expected, but got %i", *buffer_count); } else if (strcmp(key, "buffer_size") == 0) { rc = Tcl_GetIntFromObj(interp, val_obj, buffer_size); TCL_CHECK_MSG(rc, "Expected integer value for buffer_size"); TCL_CONDITION(*buffer_size >= 0, "Positive value for buffer_size " "expected, but got %i", *buffer_size); } else { TCL_RETURN_ERROR("Invalid key for key-value argument: %s\n", key); return TCL_ERROR; } } Tcl_DictObjDone(&search); return TCL_OK; }
struct t_hashtable * weechat_tcl_dict_to_hashtable (Tcl_Interp *interp, Tcl_Obj *dict, int size, const char *type_keys, const char *type_values) { struct t_hashtable *hashtable; Tcl_DictSearch search; Tcl_Obj *key, *value; int done; hashtable = weechat_hashtable_new (size, type_keys, type_values, NULL, NULL); if (!hashtable) return NULL; if (Tcl_DictObjFirst (interp, dict, &search, &key, &value, &done) == TCL_OK) { for (; !done ; Tcl_DictObjNext(&search, &key, &value, &done)) { if (strcmp (type_values, WEECHAT_HASHTABLE_STRING) == 0) { weechat_hashtable_set (hashtable, Tcl_GetString (key), Tcl_GetString (value)); } else if (strcmp (type_values, WEECHAT_HASHTABLE_POINTER) == 0) { weechat_hashtable_set (hashtable, Tcl_GetString (key), plugin_script_str2ptr (weechat_tcl_plugin, NULL, NULL, Tcl_GetString (value))); } } } Tcl_DictObjDone(&search); return hashtable; }
static int QueryConfigObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, struct Tcl_Obj *const *objv) { QCCD *cdPtr = clientData; Tcl_Obj *pkgName = cdPtr->pkg; Tcl_Obj *pDB, *pkgDict, *val, *listPtr; int n, index; static const char *const subcmdStrings[] = { "get", "list", NULL }; enum subcmds { CFG_GET, CFG_LIST }; Tcl_DString conv; Tcl_Encoding venc = NULL; const char *value; if ((objc < 2) || (objc > 3)) { Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg?"); return TCL_ERROR; } if (Tcl_GetIndexFromObj(interp, objv[1], subcmdStrings, "subcommand", 0, &index) != TCL_OK) { return TCL_ERROR; } pDB = GetConfigDict(interp); if (Tcl_DictObjGet(interp, pDB, pkgName, &pkgDict) != TCL_OK || pkgDict == NULL) { /* * Maybe a Tcl_Panic is better, because the package data has to be * present. */ Tcl_SetObjResult(interp, Tcl_NewStringObj("package not known", -1)); Tcl_SetErrorCode(interp, "TCL", "FATAL", "PKGCFG_BASE", TclGetString(pkgName), NULL); return TCL_ERROR; } switch ((enum subcmds) index) { case CFG_GET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "key"); return TCL_ERROR; } if (Tcl_DictObjGet(interp, pkgDict, objv[2], &val) != TCL_OK || val == NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj("key not known", -1)); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CONFIG", TclGetString(objv[2]), NULL); return TCL_ERROR; } if (cdPtr->encoding) { venc = Tcl_GetEncoding(interp, cdPtr->encoding); if (!venc) { return TCL_ERROR; } } /* * Value is stored as-is in a byte array, see Bug [9b2e636361], * so we have to decode it first. */ value = (const char *) Tcl_GetByteArrayFromObj(val, &n); value = Tcl_ExternalToUtfDString(venc, value, n, &conv); Tcl_SetObjResult(interp, Tcl_NewStringObj(value, Tcl_DStringLength(&conv))); Tcl_DStringFree(&conv); return TCL_OK; case CFG_LIST: if (objc != 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); return TCL_ERROR; } Tcl_DictObjSize(interp, pkgDict, &n); listPtr = Tcl_NewListObj(n, NULL); if (!listPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "insufficient memory to create list", -1)); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); return TCL_ERROR; } if (n) { Tcl_DictSearch s; Tcl_Obj *key; int done; for (Tcl_DictObjFirst(interp, pkgDict, &s, &key, NULL, &done); !done; Tcl_DictObjNext(&s, &key, NULL, &done)) { Tcl_ListObjAppendElement(NULL, listPtr, key); } } Tcl_SetObjResult(interp, listPtr); return TCL_OK; default: Tcl_Panic("QueryConfigObjCmd: Unknown subcommand to 'pkgconfig'. This can't happen"); break; } return TCL_ERROR; }