/**
* account_new - Create a new Account
+ * @param name Name for the Account
+ * @param parent Parent Config Subset
* @retval ptr New Account
*/
-struct Account *account_new(void)
+struct Account *account_new(const char *name, struct ConfigSubset *parent)
{
struct Account *a = mutt_mem_calloc(1, sizeof(struct Account));
STAILQ_INIT(&a->mailboxes);
a->notify = notify_new(a, NT_ACCOUNT);
-
- return a;
-}
-
-/**
- * account_add_config - Add some inherited Config items
- * @param a Account to add to
- * @param cs Parent Config set
- * @param name Account name
- * @param var_names Names of Config items
- * @retval bool True, if Config was successfully added
- */
-bool account_add_config(struct Account *a, const struct ConfigSet *cs,
- const char *name, const char *var_names[])
-{
- if (!a || !cs || !name || !var_names)
- return false;
-
- size_t count = 0;
- for (; var_names[count]; count++)
- ;
-
a->name = mutt_str_strdup(name);
- a->cs = cs;
- a->var_names = var_names;
- a->vars = mutt_mem_calloc(count, sizeof(struct HashElem *));
- a->num_vars = count;
-
- char a_name[64];
-
- for (size_t i = 0; i < a->num_vars; i++)
- {
- struct HashElem *parent = cs_get_elem(cs, a->var_names[i]);
- if (!parent)
- {
- mutt_debug(LL_DEBUG1, "%s doesn't exist\n", a->var_names[i]);
- return false;
- }
-
- snprintf(a_name, sizeof(a_name), "%s:%s", name, a->var_names[i]);
- a->vars[i] = cs_inherit_variable(cs, parent, a_name);
- if (!a->vars[i])
- {
- mutt_debug(LL_DEBUG1, "failed to create %s\n", a_name);
- return false;
- }
- }
-
- return true;
-}
-
-/**
- * account_free_config - Remove an Account's Config items
- * @param a Account
- */
-void account_free_config(struct Account *a)
-{
- if (!a)
- return;
+ a->sub = cs_subset_new(name, parent);
- char child[128];
- struct Buffer *err = mutt_buffer_alloc(128);
-
- for (size_t i = 0; i < a->num_vars; i++)
- {
- snprintf(child, sizeof(child), "%s:%s", a->name, a->var_names[i]);
- mutt_buffer_reset(err);
- int result = cs_str_reset(a->cs, child, err);
- if (CSR_RESULT(result) != CSR_SUCCESS)
- mutt_debug(LL_DEBUG1, "reset failed for %s: %s\n", child, mutt_b2s(err));
- mutt_hash_delete(a->cs->hash, child, NULL);
- }
-
- mutt_buffer_free(&err);
- FREE(&a->name);
- FREE(&a->vars);
+ return a;
}
/**
a->free_adata(&a->adata);
notify_free(&a->notify);
- account_free_config(a);
+ // account_free_config(a);
+ cs_subset_free(&a->sub);
+ FREE(&a->name);
FREE(ptr);
}
-
-/**
- * account_set_value - Set an Account-specific config item
- * @param a Account
- * @param vid Value ID (index into Account's HashElem's)
- * @param value Native pointer/value to set
- * @param err Buffer for error messages
- * @retval num Result, e.g. #CSR_SUCCESS
- */
-int account_set_value(const struct Account *a, size_t vid, intptr_t value, struct Buffer *err)
-{
- if (!a)
- return CSR_ERR_CODE;
- if (vid >= a->num_vars)
- return CSR_ERR_UNKNOWN;
-
- struct HashElem *he = a->vars[vid];
- return cs_he_native_set(a->cs, he, value, err);
-}
-
-/**
- * account_get_value - Get an Account-specific config item
- * @param a Account
- * @param vid Value ID (index into Account's HashElem's)
- * @param result Buffer for results or error messages
- * @retval num Result, e.g. #CSR_SUCCESS
- */
-int account_get_value(const struct Account *a, size_t vid, struct Buffer *result)
-{
- if (!a)
- return CSR_ERR_CODE;
- if (vid >= a->num_vars)
- return CSR_ERR_UNKNOWN;
-
- struct HashElem *he = a->vars[vid];
-
- if ((he->type & DT_INHERITED) && (DTYPE(he->type) == 0))
- {
- struct Inheritance *i = he->data;
- he = i->parent;
- }
-
- return cs_he_string_get(a->cs, he, result);
-}
void *adata; ///< Private data (for Mailbox backends)
void (*free_adata)(void **); ///< Callback function to free private data
- char *name; ///< Name of Account
- const struct ConfigSet *cs; ///< Parent ConfigSet
- const char **var_names; ///< Array of the names of local config items
- size_t num_vars; ///< Number of local config items
- struct HashElem **vars; ///< Array of the HashElems of local config items
+ char *name; ///< Name of Account
+ struct ConfigSubset *sub; ///< Inherited config items
};
TAILQ_HEAD(AccountList, Account);
NT_ACCOUNT_REMOVE, ///< An Account is about to be destroyed
};
-bool account_add_config(struct Account *a, const struct ConfigSet *cs, const char *name, const char *var_names[]);
void account_free(struct Account **ptr);
-void account_free_config(struct Account *a);
-int account_get_value(const struct Account *a, size_t vid, struct Buffer *result);
bool account_mailbox_add(struct Account *a, struct Mailbox *m);
bool account_mailbox_remove(struct Account *a, struct Mailbox *m);
-struct Account *account_new(void);
-int account_set_value(const struct Account *a, size_t vid, intptr_t value, struct Buffer *err);
+struct Account *account_new(const char *name, struct ConfigSubset *parent);
#endif /* MUTT_ACCOUNT_H */
struct Account *a = mx_ac_find(m);
if (!a)
{
- a = account_new();
+ a = account_new(NULL, NeoMutt->sub);
a->magic = m->magic;
new_account = true;
}
struct Buffer *pathbuf;
char *realpath; ///< used for duplicate detection, context comparison, and the sidebar
char *desc;
+ struct ConfigSubset *sub; ///< Inherited config items
off_t size;
bool has_new; /**< mailbox has new mail */
goto main_ok; // TEST04: neomutt -v
}
- NeoMutt = neomutt_new();
-
Config = init_config(500);
if (!Config)
goto main_curses;
+ NeoMutt = neomutt_new(Config);
+
notify_set_parent(Config->notify, NeoMutt->notify);
if (!get_user_info(Config))
bool new_account = false;
if (!a)
{
- a = account_new();
+ a = account_new(NULL, NeoMutt->sub);
a->magic = m->magic;
new_account = true;
}
* neomutt_new - Create the master NeoMutt object
* @retval ptr New NeoMutt
*/
-struct NeoMutt *neomutt_new(void)
+struct NeoMutt *neomutt_new(struct ConfigSet *cs)
{
struct NeoMutt *n = mutt_mem_calloc(1, sizeof(*NeoMutt));
TAILQ_INIT(&n->accounts);
n->notify = notify_new(n, NT_NEOMUTT);
+ n->sub = cs_subset_new(NULL, NULL);
+ n->sub->cs = cs;
return n;
}
neomutt_account_remove(n, NULL);
notify_free(&n->notify);
+ cs_subset_free(&n->sub);
FREE(ptr);
}
struct NeoMutt
{
struct Notify *notify; ///< Notifications handler
+ struct ConfigSubset *sub; ///< Inherited config items
struct AccountList accounts; ///< List of all Accounts
};
bool neomutt_account_add(struct NeoMutt *n, struct Account *a);
bool neomutt_account_remove(struct NeoMutt *n, struct Account *a);
void neomutt_free(struct NeoMutt **ptr);
-struct NeoMutt *neomutt_new(void);
+struct NeoMutt *neomutt_new(struct ConfigSet *cs);
void neomutt_mailboxlist_clear(struct MailboxList *ml);
struct MailboxList neomutt_mailboxlist_get_all(struct NeoMutt *n, enum MailboxType magic);
mutt_buffer_reset(&err);
struct ConfigSet *cs = cs_new(30);
+ int rc = 0;
number_init(cs);
if (!TEST_CHECK(cs_register_variables(cs, Vars, 0)))
notify_observer_add(cs->notify, NT_CONFIG, 0, log_observer, 0);
const char *account = "damaged";
- const char *BrokenVarStr[] = {
- "Pineapple",
- NULL,
- };
+ const char *parent = "Pineapple";
+
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
+
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, &err);
- struct Account *a = account_new();
- bool result = account_add_config(a, cs, account, BrokenVarStr);
account_free(&a);
- if (TEST_CHECK(!result))
+ if (he)
{
- TEST_MSG("Expected error:\n");
+ TEST_MSG("This test should have failed\n");
+ return;
}
else
{
- TEST_MSG("This test should have failed\n");
- return;
+ TEST_MSG("Expected error:\n");
}
-
- const char *AccountVarStr2[] = {
- "Apple",
- "Apple",
- NULL,
- };
-
- TEST_MSG("Expect error for next test\n");
- a = account_new();
- result = account_add_config(a, cs, account, AccountVarStr2);
account_free(&a);
- if (!TEST_CHECK(!result))
+ account = "fruit";
+ a = account_new(account, sub);
+
+ struct HashElem *he1 = cs_subset_create_var(a->sub, "Apple", &err);
+ struct HashElem *he2 = cs_subset_create_var(a->sub, "Apple", &err);
+ if (!he1 || !he2 || (he1 != he2))
{
- TEST_MSG("This test should have failed\n");
+ TEST_MSG("%s\n", err.data);
return;
}
- account = "fruit";
- const char *AccountVarStr[] = {
- "Apple",
- "Cherry",
- NULL,
- };
+ account_free(&a);
- a = account_new();
+ a = account_new(account, sub);
- result = account_add_config(NULL, cs, account, AccountVarStr);
- if (!TEST_CHECK(!result))
+ he = cs_subset_create_var(NULL, "Apple", &err);
+ if (he)
return;
-
- result = account_add_config(a, NULL, account, AccountVarStr);
- if (!TEST_CHECK(!result))
+ he = cs_subset_create_var(a->sub, NULL, &err);
+ if (he)
return;
- result = account_add_config(a, cs, NULL, AccountVarStr);
- if (!TEST_CHECK(!result))
+ he = cs_subset_create_var(a->sub, "Apple", &err);
+ if (!he)
return;
- result = account_add_config(a, cs, account, NULL);
- if (!TEST_CHECK(!result))
+ he = cs_subset_create_var(a->sub, "Cherry", &err);
+ if (!he)
return;
- result = account_add_config(a, cs, account, AccountVarStr);
- if (!TEST_CHECK(result))
- return;
-
- size_t index = 0;
+ he = cs_subset_lookup(a->sub, "Apple");
mutt_buffer_reset(&err);
- int rc = account_set_value(NULL, index, 33, &err);
-
- rc = account_set_value(a, index, 33, &err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err.data);
- }
- mutt_buffer_reset(&err);
- rc = account_set_value(a, 99, 42, &err);
- if (TEST_CHECK(CSR_RESULT(rc) == CSR_ERR_UNKNOWN))
+ rc = cs_subset_native_set(NULL, he, 33, &err);
+ if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS))
{
TEST_MSG("Expected error: %s\n", err.data);
}
return;
}
- mutt_buffer_reset(&err);
- rc = account_get_value(NULL, index, &err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_ERR_CODE))
+ rc = cs_subset_native_set(a->sub, NULL, 33, &err);
+ if (TEST_CHECK(CSR_RESULT(rc) != CSR_SUCCESS))
{
- TEST_MSG("%s\n", err.data);
+ TEST_MSG("Expected error: %s\n", err.data);
+ }
+ else
+ {
+ TEST_MSG("This test should have failed\n");
+ return;
}
- rc = account_get_value(a, index, &err);
+ rc = cs_subset_native_set(a->sub, he, 33, &err);
if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
{
TEST_MSG("%s\n", err.data);
}
- else
- {
- TEST_MSG("%s = %s\n", AccountVarStr[index], err.data);
- }
- index++;
mutt_buffer_reset(&err);
- rc = account_get_value(a, index, &err);
+ rc = cs_subset_string_get(a->sub, he, &err);
if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
{
TEST_MSG("%s\n", err.data);
}
else
{
- TEST_MSG("%s = %s\n", AccountVarStr[index], err.data);
+ TEST_MSG("%s = %s\n", he->key.strkey, err.data);
}
+ he = cs_subset_lookup(a->sub, "Cherry");
mutt_buffer_reset(&err);
- rc = account_get_value(a, 99, &err);
- if (TEST_CHECK(CSR_RESULT(rc) == CSR_ERR_UNKNOWN))
+ rc = cs_subset_string_get(a->sub, he, &err);
+ if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
{
- TEST_MSG("Expected error\n");
+ TEST_MSG("%s\n", err.data);
}
else
{
- TEST_MSG("This test should have failed\n");
- return;
+ TEST_MSG("%s = %s\n", he->key.strkey, err.data);
}
const char *name = "fruit:Apple";
return;
}
- struct HashElem *he = cs_get_elem(cs, name);
+ he = cs_get_elem(cs, name);
if (!TEST_CHECK(he != NULL))
return;
account_free(NULL);
account_free(&a);
+ cs_subset_free(&sub);
cs_free(&cs);
FREE(&err.data);
log_line(__func__);
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarAddr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarAddr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
mutt_buffer_reset(err);
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
VarMango = false;
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
VarOlive = ANIMAL_BADGER;
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
VarOlive = 123;
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarMb[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarMb);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
mutt_buffer_reset(err);
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
VarOlive = 123;
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
mutt_buffer_reset(err);
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarRegex[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarRegex);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
mutt_buffer_reset(err);
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarAddr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarAddr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
mutt_buffer_reset(err);
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
VarStrawberry = SORT_SUBJECT;
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}
char child[128];
snprintf(child, sizeof(child), "%s:%s", account, parent);
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
+ struct ConfigSubset *sub = cs_subset_new(NULL, NULL);
+ sub->cs = cs;
+ struct Account *a = account_new(account, sub);
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
+ struct HashElem *he = cs_subset_create_var(a->sub, parent, err);
+ if (!he)
+ {
+ TEST_MSG("Error: %s\n", err->data);
+ goto ti_out;
+ }
// set parent
mutt_buffer_reset(err);
result = true;
ti_out:
account_free(&a);
+ cs_subset_free(&sub);
return result;
}