+++ /dev/null
-/**
- * @file
- * Type representing a path
- *
- * @authors
- * Copyright (C) 2017-2018 Richard Russon <rich@flatcap.org>
- *
- * @copyright
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * @page config_path Type: Path
- *
- * Type representing a path.
- */
-
-#include "config.h"
-#include <stddef.h>
-#include <limits.h>
-#include <stdint.h>
-#include "mutt/mutt.h"
-#include "set.h"
-#include "types.h"
-
-/**
- * path_destroy - Destroy a Path - Implements ::cst_destroy()
- */
-static void path_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
-{
- if (!cs || !var || !cdef)
- return; /* LCOV_EXCL_LINE */
-
- const char **str = (const char **) var;
- if (!*str)
- return;
-
- /* Don't free strings from the var definition */
- if (*(char **) var == (char *) cdef->initial)
- {
- *(char **) var = NULL;
- return;
- }
-
- FREE(var);
-}
-
-/**
- * path_string_set - Set a Path by string - Implements ::cst_string_set()
- */
-static int path_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 */
-
- /* Store empty strings as NULL */
- if (value && (value[0] == '\0'))
- value = NULL;
-
- if (!value && (cdef->type & DT_NOT_EMPTY))
- {
- mutt_buffer_printf(err, "Option %s may not be empty", cdef->name);
- return CSR_ERR_INVALID | CSR_INV_VALIDATOR;
- }
-
- int rc = CSR_SUCCESS;
-
- if (var)
- {
- if (mutt_str_strcmp(value, (*(char **) var)) == 0)
- return CSR_SUCCESS | CSR_SUC_NO_CHANGE;
-
- if (cdef->validator)
- {
- rc = cdef->validator(cs, cdef, (intptr_t) value, err);
-
- if (CSR_RESULT(rc) != CSR_SUCCESS)
- return rc | CSR_INV_VALIDATOR;
- }
-
- path_destroy(cs, var, cdef);
-
- const char *str = mutt_str_strdup(value);
- if (!str)
- rc |= CSR_SUC_EMPTY;
-
- *(const char **) var = str;
- }
- else
- {
- /* we're already using the initial value */
- if (*(char **) cdef->var == (char *) cdef->initial)
- *(char **) cdef->var = mutt_str_strdup((char *) cdef->initial);
-
- if (cdef->type & DT_INITIAL_SET)
- FREE(&cdef->initial);
-
- cdef->type |= DT_INITIAL_SET;
- cdef->initial = IP mutt_str_strdup(value);
- }
-
- return rc;
-}
-
-/**
- * path_string_get - Get a Path as a string - Implements ::cst_string_get()
- */
-static int path_string_get(const struct ConfigSet *cs, void *var,
- const struct ConfigDef *cdef, struct Buffer *result)
-{
- if (!cs || !cdef)
- return CSR_ERR_CODE; /* LCOV_EXCL_LINE */
-
- const char *str = NULL;
-
- if (var)
- str = *(const char **) var;
- else
- str = (char *) cdef->initial;
-
- if (!str)
- return CSR_SUCCESS | CSR_SUC_EMPTY; /* empty string */
-
- mutt_buffer_addstr(result, str);
- return CSR_SUCCESS;
-}
-
-/**
- * path_native_set - Set a Path config item by string - Implements ::cst_native_set()
- */
-static int path_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 */
-
- const char *str = (const char *) value;
-
- /* Store empty strings as NULL */
- if (str && (str[0] == '\0'))
- value = 0;
-
- if ((value == 0) && (cdef->type & DT_NOT_EMPTY))
- {
- mutt_buffer_printf(err, "Option %s may not be empty", cdef->name);
- return CSR_ERR_INVALID | CSR_INV_VALIDATOR;
- }
-
- if (mutt_str_strcmp((const char *) value, (*(char **) var)) == 0)
- return CSR_SUCCESS | CSR_SUC_NO_CHANGE;
-
- int rc;
-
- if (cdef->validator)
- {
- rc = cdef->validator(cs, cdef, value, err);
-
- if (CSR_RESULT(rc) != CSR_SUCCESS)
- return rc | CSR_INV_VALIDATOR;
- }
-
- path_destroy(cs, var, cdef);
-
- str = mutt_str_strdup(str);
- rc = CSR_SUCCESS;
- if (!str)
- rc |= CSR_SUC_EMPTY;
-
- *(const char **) var = str;
- return rc;
-}
-
-/**
- * path_native_get - Get a string from a Path config item - Implements ::cst_native_get()
- */
-static intptr_t path_native_get(const struct ConfigSet *cs, void *var,
- const struct ConfigDef *cdef, struct Buffer *err)
-{
- if (!cs || !var || !cdef)
- return INT_MIN; /* LCOV_EXCL_LINE */
-
- const char *str = *(const char **) var;
-
- return (intptr_t) str;
-}
-
-/**
- * path_reset - Reset a Path to its initial value - Implements ::cst_reset()
- */
-static int path_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 */
-
- int rc = CSR_SUCCESS;
-
- const char *path = (const char *) cdef->initial;
- if (!path)
- rc |= CSR_SUC_EMPTY;
-
- if (mutt_str_strcmp(path, (*(char **) var)) == 0)
- return rc | CSR_SUC_NO_CHANGE;
-
- if (cdef->validator)
- {
- rc = cdef->validator(cs, cdef, cdef->initial, err);
-
- if (CSR_RESULT(rc) != CSR_SUCCESS)
- return rc | CSR_INV_VALIDATOR;
- }
-
- path_destroy(cs, var, cdef);
-
- if (!path)
- rc |= CSR_SUC_EMPTY;
-
- *(const char **) var = path;
- return rc;
-}
-
-/**
- * path_init - Register the Path config type
- * @param cs Config items
- */
-void path_init(struct ConfigSet *cs)
-{
- const struct ConfigSetType cst_path = {
- "path", path_string_set, path_string_get, path_native_set,
- path_native_get, path_reset, path_destroy,
- };
- cs_register_type(cs, DT_PATH, &cst_path);
-}
** check only happens after the \fIfirst\fP edit of the file). When set
** to \fIno\fP, composition will never be aborted.
*/
- { "alias_file", DT_PATH, &C_AliasFile, IP "~/.neomuttrc" },
+ { "alias_file", DT_STRING|DT_PATH, &C_AliasFile, IP "~/.neomuttrc" },
/*
** .pp
** The default file in which to save aliases created by the
** .pp
** For an explanation of "soft-fill", see the $$index_format documentation.
*/
- { "attach_save_dir", DT_PATH, &C_AttachSaveDir, IP "./" },
+ { "attach_save_dir", DT_STRING|DT_PATH, &C_AttachSaveDir, IP "./" },
/*
** .pp
** The directory where attachments are saved.
*/
#endif
#ifdef USE_SSL
- { "certificate_file", DT_PATH, &C_CertificateFile, IP "~/.mutt_certificates" },
+ { "certificate_file", DT_STRING|DT_PATH, &C_CertificateFile, IP "~/.mutt_certificates" },
/*
** .pp
** This variable specifies the file where the certificates you trust
** rest of the string are expanded in the \fIC\fP locale (that is in US
** English).
*/
- { "debug_file", DT_PATH, &C_DebugFile, IP "~/.neomuttdebug" },
+ { "debug_file", DT_STRING|DT_PATH, &C_DebugFile, IP "~/.neomuttdebug" },
/*
** .pp
** Debug logging is controlled by the variables \fC$$debug_file\fP and \fC$$debug_level\fP.
** misinterpreting the line as a mbox message separator).
*/
#ifdef USE_SSL_OPENSSL
- { "entropy_file", DT_PATH, &C_EntropyFile, 0 },
+ { "entropy_file", DT_STRING|DT_PATH, &C_EntropyFile, 0 },
/*
** .pp
** The file which includes random data that is used to initialize SSL
** .pp
** If set, flagged messages can't be deleted.
*/
- { "folder", DT_PATH|DT_MAILBOX, &C_Folder, IP "~/Mail" },
+ { "folder", DT_STRING|DT_PATH|DT_MAILBOX, &C_Folder, IP "~/Mail" },
/*
** .pp
** Specifies the default location of your mailboxes. A "+" or "=" at the
** The $$weed setting applies.
*/
#ifdef USE_HCACHE
- { "header_cache", DT_PATH, &C_HeaderCache, 0 },
+ { "header_cache", DT_STRING|DT_PATH, &C_HeaderCache, 0 },
/*
** .pp
** This variable points to the header cache database.
** the string history buffer per category. The buffer is cleared each time the
** variable is set.
*/
- { "history_file", DT_PATH, &C_HistoryFile, IP "~/.mutthistory" },
+ { "history_file", DT_STRING|DT_PATH, &C_HistoryFile, IP "~/.mutthistory" },
/*
** .pp
** The file in which NeoMutt will save its history.
** the \fInot\fP operator "!". Only files whose names match this mask
** will be shown. The match is always case-sensitive.
*/
- { "mbox", DT_PATH|DT_MAILBOX|R_INDEX|R_PAGER, &C_Mbox, IP "~/mbox" },
+ { "mbox", DT_STRING|DT_PATH|DT_MAILBOX|R_INDEX|R_PAGER, &C_Mbox, IP "~/mbox" },
/*
** .pp
** This specifies the folder into which read mail in your $$spoolfile
** every once in a while, since it can be a little slow
** (especially for large folders).
*/
- { "message_cachedir", DT_PATH, &C_MessageCachedir, 0 },
+ { "message_cachedir", DT_STRING|DT_PATH, &C_MessageCachedir, 0 },
/*
** .pp
** Set this to a directory and NeoMutt will cache copies of messages from
** into this command.
*/
#ifdef USE_NNTP
- { "news_cache_dir", DT_PATH, &C_NewsCacheDir, IP "~/.neomutt" },
+ { "news_cache_dir", DT_STRING|DT_PATH, &C_NewsCacheDir, IP "~/.neomutt" },
/*
** .pp
** This variable pointing to directory where NeoMutt will save cached news
** .pp
** Character set of newsgroups descriptions.
*/
- { "newsrc", DT_PATH, &C_Newsrc, IP "~/.newsrc" },
+ { "newsrc", DT_STRING|DT_PATH, &C_Newsrc, IP "~/.newsrc" },
/*
** .pp
** The file, containing info about subscribed newsgroups - names and
** Please use $$pgp_default_key or $$smime_default_key.
** (Crypto only)
*/
- { "postponed", DT_PATH|DT_MAILBOX|R_INDEX, &C_Postponed, IP "~/postponed" },
+ { "postponed", DT_STRING|DT_PATH|DT_MAILBOX|R_INDEX, &C_Postponed, IP "~/postponed" },
/*
** .pp
** NeoMutt allows you to indefinitely "$postpone sending a message" which
** .pp
** Also see $$postponed variable.
*/
- { "record", DT_PATH|DT_MAILBOX, &C_Record, IP "~/sent" },
+ { "record", DT_STRING|DT_PATH|DT_MAILBOX, &C_Record, IP "~/sent" },
/*
** .pp
** This specifies the file into which your outgoing messages should be
** unless you really know what you are doing, and are prepared to take
** some heat from netiquette guardians.
*/
- { "signature", DT_PATH, &C_Signature, IP "~/.signature" },
+ { "signature", DT_STRING|DT_PATH, &C_Signature, IP "~/.signature" },
/*
** .pp
** Specifies the filename of your signature, which is appended to all
** \fIset\fP by default.
** (S/MIME only)
*/
- { "smime_ca_location", DT_PATH, &C_SmimeCaLocation, 0 },
+ { "smime_ca_location", DT_STRING|DT_PATH, &C_SmimeCaLocation, 0 },
/*
** .pp
** This variable contains the name of either a directory, or a file which
** contains trusted certificates for use with OpenSSL.
** (S/MIME only)
*/
- { "smime_certificates", DT_PATH, &C_SmimeCertificates, 0 },
+ { "smime_certificates", DT_STRING|DT_PATH, &C_SmimeCertificates, 0 },
/*
** .pp
** Since for S/MIME there is no pubring/secring as with PGP, NeoMutt has to handle
** (S/MIME only)
*/
#ifdef CRYPT_BACKEND_CLASSIC_SMIME
- { "smime_keys", DT_PATH, &C_SmimeKeys, 0 },
+ { "smime_keys", DT_STRING|DT_PATH, &C_SmimeKeys, 0 },
/*
** .pp
** Since for S/MIME there is no pubring/secring as with PGP, NeoMutt has to handle
** match will append to the previous, using this variable's value as a
** separator.
*/
- { "spoolfile", DT_PATH|DT_MAILBOX, &C_Spoolfile, 0 },
+ { "spoolfile", DT_STRING|DT_PATH|DT_MAILBOX, &C_Spoolfile, 0 },
/*
** .pp
** If your spool mailbox is in a non-default place where NeoMutt can't find
*/
#ifdef USE_SSL
#ifdef USE_SSL_GNUTLS
- { "ssl_ca_certificates_file", DT_PATH, &C_SslCaCertificatesFile, 0 },
+ { "ssl_ca_certificates_file", DT_STRING|DT_PATH, &C_SslCaCertificatesFile, 0 },
/*
** .pp
** This variable specifies a file containing trusted CA certificates.
** syntax and more details. (Note: GnuTLS version 2.1.7 or higher is
** required.)
*/
- { "ssl_client_cert", DT_PATH, &C_SslClientCert, 0 },
+ { "ssl_client_cert", DT_STRING|DT_PATH, &C_SslClientCert, 0 },
/*
** .pp
** The file containing a client certificate and its associated private
** .pp
** A value of zero or less will cause NeoMutt to never time out.
*/
- { "tmpdir", DT_PATH, &C_Tmpdir, IP "/tmp" },
+ { "tmpdir", DT_STRING|DT_PATH, &C_Tmpdir, IP "/tmp" },
/*
** .pp
** This variable allows you to specify where NeoMutt will place its
** .dt 7 .dd R .dd Your address appears in the "Reply-To:" header field but none of the above applies.
** .de
*/
- { "trash", DT_PATH|DT_MAILBOX, &C_Trash, 0 },
+ { "trash", DT_STRING|DT_PATH|DT_MAILBOX, &C_Trash, 0 },
/*
** .pp
** If set, this variable specifies the path of the trash folder where the
+++ /dev/null
-/**
- * @file
- * Test code for the Path object
- *
- * @authors
- * Copyright (C) 2017-2018 Richard Russon <rich@flatcap.org>
- *
- * @copyright
- * This program is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation, either version 2 of the License, or (at your option) any later
- * version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#define TEST_NO_MAIN
-#include "acutest.h"
-#include "config.h"
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdio.h>
-#include "mutt/mutt.h"
-#include "config/common.h"
-#include "config/lib.h"
-#include "account.h"
-
-static char *VarApple;
-static char *VarBanana;
-static char *VarCherry;
-static char *VarDamson;
-static char *VarElderberry;
-static char *VarFig;
-static char *VarGuava;
-static char *VarHawthorn;
-static char *VarIlama;
-static char *VarJackfruit;
-static char *VarKumquat;
-static char *VarLemon;
-static char *VarMango;
-static char *VarNectarine;
-static char *VarOlive;
-static char *VarPapaya;
-static char *VarQuince;
-static char *VarRaspberry;
-static char *VarStrawberry;
-
-// clang-format off
-static struct ConfigDef Vars[] = {
- { "Apple", DT_PATH, &VarApple, IP "/apple", 0, NULL }, /* test_initial_values */
- { "Banana", DT_PATH, &VarBanana, IP "/banana", 0, NULL },
- { "Cherry", DT_PATH, &VarCherry, IP "/cherry", 0, NULL },
- { "Damson", DT_PATH, &VarDamson, 0, 0, NULL }, /* test_string_set */
- { "Elderberry", DT_PATH, &VarElderberry, IP "/elderberry", 0, NULL },
- { "Fig", DT_PATH|DT_NOT_EMPTY, &VarFig, IP "fig", 0, NULL },
- { "Guava", DT_PATH, &VarGuava, 0, 0, NULL }, /* test_string_get */
- { "Hawthorn", DT_PATH, &VarHawthorn, IP "/hawthorn", 0, NULL },
- { "Ilama", DT_PATH, &VarIlama, 0, 0, NULL },
- { "Jackfruit", DT_PATH, &VarJackfruit, 0, 0, NULL }, /* test_native_set */
- { "Kumquat", DT_PATH, &VarKumquat, IP "/kumquat", 0, NULL },
- { "Lemon", DT_PATH|DT_NOT_EMPTY, &VarLemon, IP "lemon", 0, NULL },
- { "Mango", DT_PATH, &VarMango, 0, 0, NULL }, /* test_native_get */
- { "Nectarine", DT_PATH, &VarNectarine, IP "/nectarine", 0, NULL }, /* test_reset */
- { "Olive", DT_PATH, &VarOlive, IP "/olive", 0, validator_fail },
- { "Papaya", DT_PATH, &VarPapaya, IP "/papaya", 0, validator_succeed }, /* test_validator */
- { "Quince", DT_PATH, &VarQuince, IP "/quince", 0, validator_warn },
- { "Raspberry", DT_PATH, &VarRaspberry, IP "/raspberry", 0, validator_fail },
- { "Strawberry", DT_PATH, &VarStrawberry, 0, 0, NULL }, /* test_inherit */
- { NULL },
-};
-// clang-format on
-
-static bool test_initial_values(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
- TEST_MSG("Apple = %s\n", VarApple);
- TEST_MSG("Banana = %s\n", VarBanana);
-
- if (!TEST_CHECK(mutt_str_strcmp(VarApple, "/apple") == 0))
- {
- TEST_MSG("Error: initial values were wrong\n");
- return false;
- }
-
- if (!TEST_CHECK(mutt_str_strcmp(VarBanana, "/banana") == 0))
- {
- TEST_MSG("Error: initial values were wrong\n");
- return false;
- }
-
- cs_str_string_set(cs, "Apple", "/etc", 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") == 0))
- {
- TEST_MSG("Apple's initial value is wrong: '%s'\n", value.data);
- FREE(&value.data);
- return false;
- }
- TEST_MSG("Apple = '%s'\n", VarApple);
- 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") == 0))
- {
- TEST_MSG("Banana's initial value is wrong: '%s'\n", value.data);
- FREE(&value.data);
- return false;
- }
- TEST_MSG("Banana = '%s'\n", VarBanana);
- TEST_MSG("Banana's initial value is '%s'\n", NONULL(value.data));
-
- mutt_buffer_reset(&value);
- rc = cs_str_initial_set(cs, "Cherry", "/tmp", &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", "/usr", &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);
- TEST_MSG("Cherry's initial value is '%s'\n", NONULL(value.data));
-
- FREE(&value.data);
- log_line(__func__);
- return true;
-}
-
-static bool test_string_set(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
-
- const char *valid[] = { "hello", "world", "world", "", NULL };
- const char *name = "Damson";
-
- 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;
- }
-
- if (rc & CSR_SUC_NO_CHANGE)
- {
- TEST_MSG("Value of %s wasn't changed\n", name);
- continue;
- }
-
- if (!TEST_CHECK(mutt_str_strcmp(VarDamson, 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(VarDamson), NONULL(valid[i]));
- short_line();
- }
-
- name = "Fig";
- 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);
- return false;
- }
-
- name = "Elderberry";
- for (unsigned int i = 0; i < mutt_array_size(valid); i++)
- {
- short_line();
- 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;
- }
-
- if (rc & CSR_SUC_NO_CHANGE)
- {
- TEST_MSG("Value of %s wasn't changed\n", name);
- continue;
- }
-
- if (!TEST_CHECK(mutt_str_strcmp(VarElderberry, 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(VarElderberry), NONULL(valid[i]));
- }
-
- log_line(__func__);
- return true;
-}
-
-static bool test_string_get(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
- const char *name = "Guava";
-
- 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;
- }
- TEST_MSG("%s = '%s', '%s'\n", name, NONULL(VarGuava), err->data);
-
- name = "Hawthorn";
- 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;
- }
- TEST_MSG("%s = '%s', '%s'\n", name, NONULL(VarHawthorn), err->data);
-
- name = "Ilama";
- rc = cs_str_string_set(cs, name, "ilama", 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;
- }
- TEST_MSG("%s = '%s', '%s'\n", name, NONULL(VarIlama), err->data);
-
- log_line(__func__);
- return true;
-}
-
-static bool test_native_set(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
-
- const char *valid[] = { "hello", "world", "world", "", NULL };
- const char *name = "Jackfruit";
-
- int rc;
- for (unsigned int i = 0; i < mutt_array_size(valid); i++)
- {
- mutt_buffer_reset(err);
- rc = cs_str_native_set(cs, name, (intptr_t) valid[i], err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
-
- if (rc & CSR_SUC_NO_CHANGE)
- {
- TEST_MSG("Value of %s wasn't changed\n", name);
- continue;
- }
-
- if (!TEST_CHECK(mutt_str_strcmp(VarJackfruit, 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(VarJackfruit), NONULL(valid[i]));
- short_line();
- }
-
- name = "Lemon";
- mutt_buffer_reset(err);
- rc = cs_str_native_set(cs, name, (intptr_t) "", 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;
- }
-
- name = "Kumquat";
- for (unsigned int i = 0; i < mutt_array_size(valid); i++)
- {
- short_line();
- mutt_buffer_reset(err);
- rc = cs_str_native_set(cs, name, (intptr_t) valid[i], err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
-
- if (rc & CSR_SUC_NO_CHANGE)
- {
- TEST_MSG("Value of %s wasn't changed\n", name);
- continue;
- }
-
- if (!TEST_CHECK(mutt_str_strcmp(VarKumquat, 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(VarKumquat), NONULL(valid[i]));
- }
-
- log_line(__func__);
- return true;
-}
-
-static bool test_native_get(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
- const char *name = "Mango";
-
- int rc = cs_str_string_set(cs, name, "mango", err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- return false;
-
- mutt_buffer_reset(err);
- intptr_t value = cs_str_native_get(cs, name, err);
- if (!TEST_CHECK(mutt_str_strcmp(VarMango, (char *) value) == 0))
- {
- TEST_MSG("Get failed: %s\n", err->data);
- return false;
- }
- TEST_MSG("%s = '%s', '%s'\n", name, VarMango, (char *) value);
-
- log_line(__func__);
- return true;
-}
-
-static bool test_reset(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
-
- const char *name = "Nectarine";
- mutt_buffer_reset(err);
-
- TEST_MSG("Initial: %s = '%s'\n", name, VarNectarine);
- int rc = cs_str_string_set(cs, name, "hello", err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- return false;
- TEST_MSG("Set: %s = '%s'\n", name, VarNectarine);
-
- rc = cs_str_reset(cs, name, err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
-
- if (!TEST_CHECK(mutt_str_strcmp(VarNectarine, "/nectarine") == 0))
- {
- TEST_MSG("Value of %s wasn't changed\n", name);
- return false;
- }
-
- TEST_MSG("Reset: %s = '%s'\n", name, VarNectarine);
-
- rc = cs_str_reset(cs, name, err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
-
- name = "Olive";
- mutt_buffer_reset(err);
-
- TEST_MSG("Initial: %s = '%s'\n", name, VarOlive);
- dont_fail = true;
- rc = cs_str_string_set(cs, name, "hello", err);
- if (!TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- return false;
- TEST_MSG("Set: %s = '%s'\n", name, VarOlive);
- 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(VarOlive, "hello") == 0))
- {
- TEST_MSG("Value of %s changed\n", name);
- return false;
- }
-
- TEST_MSG("Reset: %s = '%s'\n", name, VarOlive);
-
- log_line(__func__);
- return true;
-}
-
-static bool test_validator(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
-
- const char *name = "Papaya";
- mutt_buffer_reset(err);
- int rc = cs_str_string_set(cs, name, "hello", err);
- if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- }
- else
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
- TEST_MSG("Path: %s = %s\n", name, VarPapaya);
-
- mutt_buffer_reset(err);
- rc = cs_str_native_set(cs, name, IP "world", err);
- if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- }
- else
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
- TEST_MSG("Native: %s = %s\n", name, VarPapaya);
-
- name = "Quince";
- mutt_buffer_reset(err);
- rc = cs_str_string_set(cs, name, "hello", err);
- if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- }
- else
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
- TEST_MSG("Path: %s = %s\n", name, VarQuince);
-
- mutt_buffer_reset(err);
- rc = cs_str_native_set(cs, name, IP "world", err);
- if (TEST_CHECK(CSR_RESULT(rc) == CSR_SUCCESS))
- {
- TEST_MSG("%s\n", err->data);
- }
- else
- {
- TEST_MSG("%s\n", err->data);
- return false;
- }
- TEST_MSG("Native: %s = %s\n", name, VarQuince);
-
- name = "Raspberry";
- mutt_buffer_reset(err);
- rc = cs_str_string_set(cs, name, "hello", 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;
- }
- TEST_MSG("Path: %s = %s\n", name, VarRaspberry);
-
- mutt_buffer_reset(err);
- rc = cs_str_native_set(cs, name, IP "world", 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;
- }
- TEST_MSG("Native: %s = %s\n", name, VarRaspberry);
-
- log_line(__func__);
- return true;
-}
-
-static void dump_native(struct ConfigSet *cs, const char *parent, const char *child)
-{
- intptr_t pval = cs_str_native_get(cs, parent, NULL);
- intptr_t cval = cs_str_native_get(cs, child, NULL);
-
- TEST_MSG("%15s = %s\n", parent, (char *) pval);
- TEST_MSG("%15s = %s\n", child, (char *) cval);
-}
-
-static bool test_inherit(struct ConfigSet *cs, struct Buffer *err)
-{
- log_line(__func__);
- bool result = false;
-
- const char *account = "fruit";
- const char *parent = "Strawberry";
- char child[128];
- snprintf(child, sizeof(child), "%s:%s", account, parent);
-
- const char *AccountVarStr[] = {
- parent,
- NULL,
- };
-
- struct Account *a = account_new();
- account_add_config(a, cs, account, AccountVarStr);
-
- // set parent
- mutt_buffer_reset(err);
- int rc = cs_str_string_set(cs, parent, "hello", err);
- if (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, "world", err);
- if (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 (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 (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:
- account_free(&a);
- return result;
-}
-
-void config_path(void)
-{
- 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);
-
- path_init(cs);
- dont_fail = true;
- if (!cs_register_variables(cs, Vars, 0))
- return;
- dont_fail = false;
-
- notify_observer_add(cs->notify, NT_CONFIG, 0, log_observer, 0);
-
- set_list(cs);
-
- TEST_CHECK(test_initial_values(cs, &err));
- TEST_CHECK(test_string_set(cs, &err));
- TEST_CHECK(test_string_get(cs, &err));
- TEST_CHECK(test_native_set(cs, &err));
- TEST_CHECK(test_native_get(cs, &err));
- TEST_CHECK(test_reset(cs, &err));
- TEST_CHECK(test_validator(cs, &err));
- TEST_CHECK(test_inherit(cs, &err));
-
- cs_free(&cs);
- FREE(&err.data);
-}