static bool test_string_set(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); const char *valid[] = { "*****@*****.**", "*****@*****.**", NULL }; const char *name = "Damson"; char *addr = NULL; int rc; for (unsigned int i = 0; i < mutt_array_size(valid); i++) { mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, valid[i], err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); return false; } addr = VarDamson ? VarDamson->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, valid[i]) == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); return false; } TEST_MSG("%s = '%s', set by '%s'\n", name, NONULL(addr), NONULL(valid[i])); } name = "Elderberry"; for (unsigned int i = 0; i < mutt_array_size(valid); i++) { mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, valid[i], err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); return false; } addr = VarElderberry ? VarElderberry->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, valid[i]) == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); return false; } TEST_MSG("%s = '%s', set by '%s'\n", name, NONULL(addr), NONULL(valid[i])); } log_line(__func__); return true; }
static bool test_native_set(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); struct Address *a = address_new("*****@*****.**"); const char *name = "Ilama"; char *addr = NULL; bool result = false; mutt_buffer_reset(err); int rc = cs_str_native_set(cs, name, (intptr_t) a, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); goto tbns_out; } addr = VarIlama ? VarIlama->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, a->mailbox) == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); goto tbns_out; } TEST_MSG("%s = '%s', set by '%s'\n", name, NONULL(addr), a->mailbox); name = "Jackfruit"; mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, 0, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); goto tbns_out; } if (!TEST_CHECK(VarJackfruit == NULL)) { TEST_MSG("Value of %s wasn't changed\n", name); goto tbns_out; } addr = VarJackfruit ? VarJackfruit->mailbox : NULL; TEST_MSG("%s = '%s', set by NULL\n", name, NONULL(addr)); log_line(__func__); result = true; tbns_out: address_free(&a); return result; }
/** * long_native_set - Set a Long config item by int - Implements ::cst_native_set() */ static int long_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err) { if (!cs || !var || !cdef) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ if ((value < 0) && (cdef->type & DT_NOT_NEGATIVE)) { mutt_buffer_printf(err, "Option %s may not be negative", cdef->name); return CSR_ERR_INVALID | CSR_INV_VALIDATOR; } if (value == (*(long *) var)) return CSR_SUCCESS | CSR_SUC_NO_CHANGE; if (cdef->validator) { int rc = cdef->validator(cs, cdef, value, err); if (CSR_RESULT(rc) != CSR_SUCCESS) return rc | CSR_INV_VALIDATOR; } *(long *) var = value; return CSR_SUCCESS; }
/** * cs_he_initial_set - Set the initial value of a config item * @param cs Config items * @param he HashElem representing config item * @param value Value to set * @param err Buffer for error messages * @retval int Result, e.g. #CSR_SUCCESS */ int cs_he_initial_set(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err) { if (!cs || !he) return CSR_ERR_CODE; struct ConfigDef *cdef = NULL; const struct ConfigSetType *cst = NULL; if (he->type & DT_INHERITED) { struct Inheritance *i = he->data; cdef = i->parent->data; mutt_debug(LL_DEBUG1, "Variable '%s' is inherited type\n", cdef->name); return CSR_ERR_CODE; } cdef = he->data; 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->string_set(cs, NULL, cdef, value, err); if (CSR_RESULT(rc) != CSR_SUCCESS) return rc; cs_notify_listeners(cs, he, he->key.strkey, CE_INITIAL_SET); return CSR_SUCCESS; }
/** * address_reset - Reset an Address to its initial value - Implements ::cst_reset() */ static int address_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err) { if (!cs || !var || !cdef) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ struct Address *a = NULL; const char *initial = (const char *) cdef->initial; if (initial) a = address_new(initial); int rc = CSR_SUCCESS; if (cdef->validator) { rc = cdef->validator(cs, cdef, (intptr_t) a, err); if (CSR_RESULT(rc) != CSR_SUCCESS) { address_destroy(cs, &a, cdef); return rc | CSR_INV_VALIDATOR; } } if (!a) rc |= CSR_SUC_EMPTY; address_destroy(cs, var, cdef); *(struct Address **) var = a; return rc; }
/** * address_native_set - Set an Address config item by Address object - Implements ::cst_native_set() */ static int address_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err) { if (!cs || !var || !cdef) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ int rc; if (cdef->validator) { rc = cdef->validator(cs, cdef, value, err); if (CSR_RESULT(rc) != CSR_SUCCESS) return rc | CSR_INV_VALIDATOR; } address_free(var); struct Address *addr = address_dup((struct Address *) value); rc = CSR_SUCCESS; if (!addr) rc |= CSR_SUC_EMPTY; *(struct Address **) var = addr; return rc; }
static bool test_string_get(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); const char *name = "Fig"; char *addr = NULL; mutt_buffer_reset(err); int rc = cs_str_string_get(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Get failed: %s\n", err->data); return false; } addr = VarFig ? VarFig->mailbox : NULL; TEST_MSG("%s = '%s', '%s'\n", name, NONULL(addr), err->data); name = "Guava"; mutt_buffer_reset(err); rc = cs_str_string_get(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Get failed: %s\n", err->data); return false; } addr = VarGuava ? VarGuava->mailbox : NULL; TEST_MSG("%s = '%s', '%s'\n", name, NONULL(addr), err->data); name = "Hawthorn"; rc = cs_str_string_set(cs, name, "hawthorn", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) return false; mutt_buffer_reset(err); rc = cs_str_string_get(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Get failed: %s\n", err->data); return false; } addr = VarHawthorn ? VarHawthorn->mailbox : NULL; TEST_MSG("%s = '%s', '%s'\n", name, NONULL(addr), err->data); log_line(__func__); return true; }
/** * address_string_set - Set an Address by string - Implements ::cst_string_set() */ static int address_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err) { if (!cs || !cdef) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ struct Address *addr = NULL; /* An empty address "" will be stored as NULL */ if (var && value && (value[0] != '\0')) { addr = mutt_addr_parse_list(NULL, value); } int rc = CSR_SUCCESS; if (var) { if (cdef->validator) { rc = cdef->validator(cs, cdef, (intptr_t) addr, err); if (CSR_RESULT(rc) != CSR_SUCCESS) { address_destroy(cs, &addr, cdef); return rc | CSR_INV_VALIDATOR; } } /* ordinary variable setting */ address_destroy(cs, var, cdef); *(struct Address **) var = addr; if (!addr) rc |= CSR_SUC_EMPTY; } else { /* set the default/initial value */ if (cdef->type & DT_INITIAL_SET) FREE(&cdef->initial); cdef->type |= DT_INITIAL_SET; cdef->initial = IP mutt_str_strdup(value); } return rc; }
/** * 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; }
/** * cs_he_string_set - Set a config item by string * @param cs Config items * @param he HashElem representing config item * @param value Value to set * @param err Buffer for error messages * @retval int Result, e.g. #CSR_SUCCESS */ int cs_he_string_set(const struct ConfigSet *cs, struct HashElem *he, const char *value, struct Buffer *err) { if (!cs || !he) return CSR_ERR_CODE; 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; } if (!var) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ int rc = cst->string_set(cs, var, cdef, value, err); if (CSR_RESULT(rc) != CSR_SUCCESS) return rc; if (he->type & DT_INHERITED) { struct Inheritance *i = he->data; he->type = i->parent->type | DT_INHERITED; } if (!(rc & CSR_SUC_NO_CHANGE)) cs_notify_listeners(cs, he, he->key.strkey, CE_SET); return rc; }
/** * long_reset - Reset a Long to its initial value - Implements ::cst_reset() */ static int long_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err) { if (!cs || !var || !cdef) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ if (cdef->initial == (*(long *) var)) return CSR_SUCCESS | CSR_SUC_NO_CHANGE; if (cdef->validator) { int rc = cdef->validator(cs, cdef, cdef->initial, err); if (CSR_RESULT(rc) != CSR_SUCCESS) return (rc | CSR_INV_VALIDATOR); } *(long *) var = cdef->initial; return CSR_SUCCESS; }
/** * long_string_set - Set a Long by string - Implements ::cst_string_set() */ static int long_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err) { if (!cs || !cdef) return CSR_ERR_CODE; /* LCOV_EXCL_LINE */ long num = 0; if (!value || (value[0] == '\0') || (mutt_str_atol(value, &num) < 0)) { mutt_buffer_printf(err, "Invalid long: %s", NONULL(value)); return CSR_ERR_INVALID | CSR_INV_TYPE; } if ((num < 0) && (cdef->type & DT_NOT_NEGATIVE)) { mutt_buffer_printf(err, "Option %s may not be negative", cdef->name); return CSR_ERR_INVALID | CSR_INV_VALIDATOR; } if (var) { if (num == (*(long *) var)) return CSR_SUCCESS | CSR_SUC_NO_CHANGE; if (cdef->validator) { int rc = cdef->validator(cs, cdef, (intptr_t) num, err); if (CSR_RESULT(rc) != CSR_SUCCESS) return rc | CSR_INV_VALIDATOR; } *(long *) var = num; } else { cdef->initial = num; } return CSR_SUCCESS; }
/** * cs_he_reset - Reset a config item to its initial value * @param cs Config items * @param he HashElem representing config item * @param err Buffer for error messages * @retval int Result, e.g. #CSR_SUCCESS */ int cs_he_reset(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *err) { if (!cs || !he) return CSR_ERR_CODE; /* An inherited var that's already pointing to its parent. * Return 'success', but don't send a notification. */ if ((he->type & DT_INHERITED) && (DTYPE(he->type) == 0)) return CSR_SUCCESS; const struct ConfigSetType *cst = NULL; const struct ConfigDef *cdef = NULL; int rc = CSR_SUCCESS; if (he->type & DT_INHERITED) { struct Inheritance *i = he->data; cst = cs_get_type_def(cs, i->parent->type); cdef = i->parent->data; if (cst && cst->destroy) cst->destroy(cs, (void **) &i->var, cdef); he->type = DT_INHERITED; } else { cst = cs_get_type_def(cs, he->type); cdef = he->data; if (cst) rc = cst->reset(cs, cdef->var, cdef, err); } if ((CSR_RESULT(rc) == CSR_SUCCESS) && !(rc & CSR_SUC_NO_CHANGE)) cs_notify_listeners(cs, he, he->key.strkey, CE_RESET); return rc; }
static bool test_validator(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); char *addr = NULL; struct Address *a = address_new("*****@*****.**"); bool result = false; const char *name = "Nectarine"; mutt_buffer_reset(err); int rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarNectarine ? VarNectarine->mailbox : NULL; TEST_MSG("Address: %s = %s\n", name, NONULL(addr)); mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, IP a, err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarNectarine ? VarNectarine->mailbox : NULL; TEST_MSG("Native: %s = %s\n", name, NONULL(addr)); name = "Olive"; mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarOlive ? VarOlive->mailbox : NULL; TEST_MSG("Address: %s = %s\n", name, NONULL(addr)); mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, IP a, err); if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarOlive ? VarOlive->mailbox : NULL; TEST_MSG("Native: %s = %s\n", name, NONULL(addr)); name = "Papaya"; mutt_buffer_reset(err); rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS)) { TEST_MSG("Expected error: %s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarPapaya ? VarPapaya->mailbox : NULL; TEST_MSG("Address: %s = %s\n", name, NONULL(addr)); mutt_buffer_reset(err); rc = cs_str_native_set(cs, name, IP a, err); if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS)) { TEST_MSG("Expected error: %s\n", err->data); } else { TEST_MSG("%s\n", err->data); goto tv_out; } addr = VarPapaya ? VarPapaya->mailbox : NULL; TEST_MSG("Native: %s = %s\n", name, NONULL(addr)); result = true; tv_out: address_free(&a); log_line(__func__); return result; }
/** * dump_config - Write all the config to a file * @param cs ConfigSet to dump * @param style Output style, e.g. #CS_DUMP_STYLE_MUTT * @param flags Flags, see #ConfigDumpFlags * @param fp File to write config to */ bool dump_config(struct ConfigSet *cs, enum CsDumpStyle style, ConfigDumpFlags flags, FILE *fp) { if (!cs) return false; struct HashElem *he = NULL; struct HashElem **list = get_elem_list(cs); if (!list) return false; /* LCOV_EXCL_LINE */ bool result = true; struct Buffer *value = mutt_buffer_alloc(256); struct Buffer *initial = mutt_buffer_alloc(256); struct Buffer *tmp = mutt_buffer_alloc(256); for (size_t i = 0; list[i]; i++) { mutt_buffer_reset(value); mutt_buffer_reset(initial); he = list[i]; const int type = DTYPE(he->type); if ((type == DT_SYNONYM) && !(flags & CS_DUMP_SHOW_SYNONYMS)) continue; // if ((type == DT_DISABLED) && !(flags & CS_DUMP_SHOW_DISABLED)) // continue; if (type != DT_SYNONYM) { /* If necessary, get the current value */ if ((flags & CS_DUMP_ONLY_CHANGED) || !(flags & CS_DUMP_HIDE_VALUE) || (flags & CS_DUMP_SHOW_DEFAULTS)) { int rc = cs_he_string_get(cs, he, value); if (CSR_RESULT(rc) != CSR_SUCCESS) { result = false; /* LCOV_EXCL_LINE */ break; /* LCOV_EXCL_LINE */ } const struct ConfigDef *cdef = he->data; if (IS_SENSITIVE(*cdef) && (flags & CS_DUMP_HIDE_SENSITIVE) && !mutt_buffer_is_empty(value)) { mutt_buffer_reset(value); mutt_buffer_addstr(value, "***"); } if ((type == DT_PATH) && (value->data[0] == '/')) mutt_pretty_mailbox(value->data, value->dsize); if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING)) { mutt_buffer_reset(tmp); pretty_var(value->data, tmp); mutt_buffer_strcpy(value, tmp->data); } } /* If necessary, get the default value */ if (flags & (CS_DUMP_ONLY_CHANGED | CS_DUMP_SHOW_DEFAULTS)) { int rc = cs_he_initial_get(cs, he, initial); if (CSR_RESULT(rc) != CSR_SUCCESS) { result = false; /* LCOV_EXCL_LINE */ break; /* LCOV_EXCL_LINE */ } if ((type == DT_PATH) && !(he->type & DT_MAILBOX)) mutt_pretty_mailbox(initial->data, initial->dsize); if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) && (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING)) { mutt_buffer_reset(tmp); pretty_var(initial->data, tmp); mutt_buffer_strcpy(initial, tmp->data); } } } if (style == CS_DUMP_STYLE_MUTT) dump_config_mutt(cs, he, value, initial, flags, fp); else dump_config_neo(cs, he, value, initial, flags, fp); } FREE(&list); mutt_buffer_free(&value); mutt_buffer_free(&initial); mutt_buffer_free(&tmp); return result; }
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__); }
static bool test_reset(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); const char *name = "Lemon"; mutt_buffer_reset(err); char *addr = VarLemon ? VarLemon->mailbox : NULL; TEST_MSG("Initial: %s = '%s'\n", name, NONULL(addr)); int rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) return false; addr = VarLemon ? VarLemon->mailbox : NULL; TEST_MSG("Set: %s = '%s'\n", name, NONULL(addr)); rc = cs_str_reset(cs, name, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", err->data); return false; } addr = VarLemon ? VarLemon->mailbox : NULL; if (!TEST_CHECK(mutt_str_strcmp(addr, "*****@*****.**") == 0)) { TEST_MSG("Value of %s wasn't changed\n", name); return false; } TEST_MSG("Reset: %s = '%s'\n", name, NONULL(addr)); name = "Mango"; mutt_buffer_reset(err); TEST_MSG("Initial: %s = '%s'\n", name, VarMango->mailbox); dont_fail = true; rc = cs_str_string_set(cs, name, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) return false; TEST_MSG("Set: %s = '%s'\n", name, VarMango->mailbox); dont_fail = false; rc = cs_str_reset(cs, name, err); if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS)) { TEST_MSG("Expected error: %s\n", err->data); } else { TEST_MSG("%s\n", err->data); return false; } if (!TEST_CHECK(mutt_str_strcmp(VarMango->mailbox, "*****@*****.**") == 0)) { TEST_MSG("Value of %s changed\n", name); return false; } TEST_MSG("Reset: %s = '%s'\n", name, VarMango->mailbox); log_line(__func__); return true; }
static bool test_initial_values(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); TEST_MSG("Apple = '%s'\n", VarApple->mailbox); TEST_MSG("Banana = '%s'\n", VarBanana->mailbox); const char *apple_orig = "*****@*****.**"; const char *banana_orig = "*****@*****.**"; if (!TEST_CHECK(mutt_str_strcmp(VarApple->mailbox, apple_orig) == 0)) { TEST_MSG("Error: initial values were wrong\n"); return false; } if (!TEST_CHECK(mutt_str_strcmp(VarBanana->mailbox, banana_orig) == 0)) { TEST_MSG("Error: initial values were wrong\n"); return false; } cs_str_string_set(cs, "Apple", "*****@*****.**", err); cs_str_string_set(cs, "Banana", NULL, err); struct Buffer value; mutt_buffer_init(&value); value.dsize = 256; value.data = mutt_mem_calloc(1, value.dsize); mutt_buffer_reset(&value); int rc; mutt_buffer_reset(&value); rc = cs_str_initial_get(cs, "Apple", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } if (!TEST_CHECK(mutt_str_strcmp(value.data, apple_orig) == 0)) { TEST_MSG("Apple's initial value is wrong: '%s'\n", value.data); FREE(&value.data); return false; } TEST_MSG("Apple = '%s'\n", VarApple->mailbox); TEST_MSG("Apple's initial value is '%s'\n", value.data); mutt_buffer_reset(&value); rc = cs_str_initial_get(cs, "Banana", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } if (!TEST_CHECK(mutt_str_strcmp(value.data, banana_orig) == 0)) { TEST_MSG("Banana's initial value is wrong: '%s'\n", value.data); FREE(&value.data); return false; } TEST_MSG("Banana = '%s'\n", VarBanana ? VarBanana->mailbox : ""); TEST_MSG("Banana's initial value is '%s'\n", NONULL(value.data)); mutt_buffer_reset(&value); rc = cs_str_initial_set(cs, "Cherry", "*****@*****.**", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } mutt_buffer_reset(&value); rc = cs_str_initial_set(cs, "Cherry", "*****@*****.**", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } mutt_buffer_reset(&value); rc = cs_str_initial_get(cs, "Cherry", &value); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("%s\n", value.data); FREE(&value.data); return false; } TEST_MSG("Cherry = '%s'\n", VarCherry ? VarCherry->mailbox : ""); TEST_MSG("Cherry's initial value is '%s'\n", NONULL(value.data)); FREE(&value.data); log_line(__func__); return true; }
static bool test_inherit(struct ConfigSet *cs, struct Buffer *err) { log_line(__func__); bool result = false; const char *account = "fruit"; const char *parent = "Quince"; char child[128]; snprintf(child, sizeof(child), "%s:%s", account, parent); const char *AccountVarAddr[] = { parent, NULL, }; struct CfgAccount *ac = ac_new(cs, account, AccountVarAddr); // set parent mutt_buffer_reset(err); int rc = cs_str_string_set(cs, parent, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // set child mutt_buffer_reset(err); rc = cs_str_string_set(cs, child, "*****@*****.**", err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // reset child mutt_buffer_reset(err); rc = cs_str_reset(cs, child, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); // reset parent mutt_buffer_reset(err); rc = cs_str_reset(cs, parent, err); if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS)) { TEST_MSG("Error: %s\n", err->data); goto ti_out; } dump_native(cs, parent, child); log_line(__func__); result = true; ti_out: ac_free(cs, &ac); return result; }