/** * cs_str_native_get - Natively get the value of a string config item * @param cs Config items * @param name Name of config item * @param err Buffer for error messages * @retval intptr_t Native pointer/value */ intptr_t cs_str_native_get(const struct ConfigSet *cs, const char *name, struct Buffer *err) { if (!cs || !name) return INT_MIN; struct HashElem *he = cs_get_elem(cs, name); return cs_he_native_get(cs, he, err); }
/** * cs_str_string_get - Get a config item as a string * @param cs Config items * @param name Name of config item * @param result Buffer for results or error messages * @retval int Result, e.g. #CSR_SUCCESS */ int cs_str_string_get(const struct ConfigSet *cs, const char *name, struct Buffer *result) { if (!cs || !name) return CSR_ERR_CODE; struct HashElem *he = cs_get_elem(cs, name); if (!he) { mutt_buffer_printf(result, "Unknown var '%s'", name); return CSR_ERR_UNKNOWN; } return cs_he_string_get(cs, he, result); }
/** * cs_str_reset - Reset a config item to its initial value * @param cs Config items * @param name Name of config item * @param err Buffer for error messages * @retval int Result, e.g. #CSR_SUCCESS */ int cs_str_reset(const struct ConfigSet *cs, const char *name, struct Buffer *err) { if (!cs || !name) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ struct HashElem *he = cs_get_elem(cs, name); if (!he) { mutt_buffer_printf(err, "Unknown var '%s'", name); return CSR_ERR_UNKNOWN; } return cs_he_reset(cs, he, err); }
/** * cs_str_initial_set - Set the initial value of a config item * @param cs Config items * @param name Name of config item * @param value Value to set * @param err Buffer for error messages * @retval int Result, e.g. #CSR_SUCCESS */ int cs_str_initial_set(const struct ConfigSet *cs, const char *name, const char *value, struct Buffer *err) { if (!cs || !name) return CSR_ERR_CODE; struct HashElem *he = cs_get_elem(cs, name); if (!he) { mutt_buffer_printf(err, "Unknown var '%s'", name); return CSR_ERR_UNKNOWN; } return cs_he_initial_set(cs, he, value, err); }
/** * cs_str_native_set - Natively set the value of a string config item * @param cs Config items * @param name Name of config item * @param value Native pointer/value to set * @param err Buffer for error messages * @retval int Result, e.g. #CSR_SUCCESS */ int cs_str_native_set(const struct ConfigSet *cs, const char *name, intptr_t value, struct Buffer *err) { if (!cs || !name) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ struct HashElem *he = cs_get_elem(cs, name); if (!he) { mutt_buffer_printf(err, "Unknown var '%s'", name); return CSR_ERR_UNKNOWN; } const struct ConfigDef *cdef = NULL; const struct ConfigSetType *cst = NULL; void *var = NULL; if (he->type & DT_INHERITED) { struct Inheritance *i = he->data; cdef = i->parent->data; var = &i->var; cst = cs_get_type_def(cs, i->parent->type); } else { cdef = he->data; var = cdef->var; cst = cs_get_type_def(cs, he->type); } if (!cst) { mutt_debug(LL_DEBUG1, "Variable '%s' has an invalid type %d\n", cdef->name, he->type); return CSR_ERR_CODE; } int rc = cst->native_set(cs, var, cdef, value, err); if (CSR_RESULT(rc) == CSR_SUCCESS) { if (he->type & DT_INHERITED) he->type = cdef->type | DT_INHERITED; if (!(rc & CSR_SUC_NO_CHANGE)) cs_notify_listeners(cs, he, cdef->name, CE_SET); } return rc; }
/** * create_synonym - Create an alternative name for a config item * @param cs Config items * @param cdef Variable definition * @param err Buffer for error messages * @retval ptr New HashElem representing the config item synonym */ static struct HashElem *create_synonym(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err) { if (!cs || !cdef) return NULL; /* LCOV_EXCL_LINE */ const char *name = (const char *) cdef->initial; struct HashElem *parent = cs_get_elem(cs, name); if (!parent) { mutt_buffer_printf(err, "No such variable: %s", name); return NULL; } struct HashElem *child = mutt_hash_typed_insert(cs->hash, cdef->name, cdef->type, (void *) cdef); if (!child) return NULL; /* LCOV_EXCL_LINE */ cdef->var = parent; return child; }
void config_set(void) { log_line(__func__); struct Buffer err; mutt_buffer_init(&err); err.dsize = 256; err.data = mutt_mem_calloc(1, err.dsize); mutt_buffer_reset(&err); struct ConfigSet *cs = cs_new(30); if (!TEST_CHECK(cs != NULL)) return; cs_add_listener(cs, log_listener); cs_add_listener(cs, log_listener); /* dupe */ cs_remove_listener(cs, log_listener); cs_remove_listener(cs, log_listener); /* non-existant */ const struct ConfigSetType cst_dummy = { "dummy", NULL, NULL, NULL, NULL, NULL, NULL, }; if (TEST_CHECK(!cs_register_type(cs, DT_STRING, &cst_dummy))) { TEST_MSG("Expected error\n"); } else { TEST_MSG("This test should have failed\n"); return; } const struct ConfigSetType cst_dummy2 = { "dummy2", dummy_string_set, dummy_string_get, dummy_native_set, dummy_native_get, dummy_reset, dummy_destroy, }; if (TEST_CHECK(!cs_register_type(cs, 25, &cst_dummy2))) { TEST_MSG("Expected error\n"); } else { TEST_MSG("This test should have failed\n"); return; } bool_init(cs); bool_init(cs); /* second one should fail */ if (TEST_CHECK(!cs_register_variables(cs, Vars, 0))) { TEST_MSG("Expected error\n"); } else { TEST_MSG("This test should have failed\n"); return; } const char *name = "Unknown"; int result = cs_str_string_set(cs, name, "hello", &err); if (TEST_CHECK(CSR_RESULT(result) == CSR_ERR_UNKNOWN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 1\n"); return; } result = cs_str_string_get(cs, name, &err); if (TEST_CHECK(CSR_RESULT(result) == CSR_ERR_UNKNOWN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 2\n"); return; } result = cs_str_native_set(cs, name, IP "hello", &err); if (TEST_CHECK(CSR_RESULT(result) == CSR_ERR_UNKNOWN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 3\n"); return; } intptr_t native = cs_str_native_get(cs, name, &err); if (TEST_CHECK(native == INT_MIN)) { TEST_MSG("Expected error: Unknown var '%s'\n", name); } else { TEST_MSG("This should have failed 4\n"); return; } struct HashElem *he = cs_get_elem(cs, "Banana"); if (!TEST_CHECK(he != NULL)) return; set_list(cs); const struct ConfigSetType *cst = cs_get_type_def(cs, 15); if (!TEST_CHECK(!cst)) return; cs_free(&cs); FREE(&err.data); log_line(__func__); }