+/*
+ * prototypes
+ */
+static const struct mapping_t* get_sortmap (struct option_t* option);
+static int parse_sort (struct option_t* dst, const char *s,
+ const struct mapping_t *map,
+ char* errbuf, ssize_t errlen);
+
+static HASH *ConfigOptions = NULL;
+
+/* for synonym warning reports: synonym found during parsing */
+typedef struct syn_t {
+ struct syn_t *next;
+ char* f; /* file */
+ int l; /* line */
+ struct option_t* n; /* new */
+ struct option_t* o; /* old */
+} syn_t;
+
+DO_INIT(syn_t, syn);
+static void syn_wipe(syn_t *syn) {
+ p_delete(&syn->f);
+}
+DO_NEW(syn_t, syn);
+DO_DELETE(syn_t, syn);
+DO_SLIST(syn_t, syn, syn_delete);
+
+/* for synonym warning reports: list of synonyms found */
+static syn_t *Synonyms = NULL;
+/* for synonym warning reports: current rc file */
+static const char* CurRCFile = NULL;
+/* for synonym warning reports: current rc line */
+static int CurRCLine = 0;
+
+/* prototypes for checking for special vars */
+static int check_dsn_return (const char* option, unsigned long val,
+ char* errbuf, ssize_t errlen);
+static int check_dsn_notify (const char* option, unsigned long val,
+ char* errbuf, ssize_t errlen);
+static int check_history (const char* option, unsigned long val,
+ char* errbuf, ssize_t errlen);
+/* this checks that numbers are >= 0 */
+static int check_num (const char* option, unsigned long val,
+ char* errbuf, ssize_t errlen);
+
+/* use this to check only */
+static int check_special (const char* option, unsigned long val,
+ char* errbuf, ssize_t errlen);
+
+/* variable <-> sanity check function mappings
+ * when changing these, make sure the proper _from_string handler
+ * does this checking!
+ */
+static struct {
+ const char* name;
+ int (*check) (const char* option, unsigned long val,
+ char* errbuf, ssize_t errlen);
+} SpecialVars[] = {
+ { "dsn_notify", check_dsn_notify },
+ { "dsn_return", check_dsn_return },
+#if defined (USE_LIBESMTP) && (defined (USE_SSL) || defined (USE_GNUTLS))
+ { "smtp_use_tls", mutt_libesmtp_check_usetls },
+#endif
+ { "history", check_history },
+ { "pager_index_lines", check_num },
+ /* last */
+ { NULL, NULL }
+};
+
+/* protos for config type handles: convert value to string */
+static void bool_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void num_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void str_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void quad_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void sort_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void rx_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void magic_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void addr_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void user_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+static void sys_to_string (char* dst, ssize_t dstlen, struct option_t* option);
+
+/* protos for config type handles: convert to value from string */
+static int bool_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int num_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int str_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int path_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int quad_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int sort_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int rx_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int magic_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int addr_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+static int user_from_string (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+
+static struct {
+ unsigned short type;
+ void (*opt_to_string) (char* dst, ssize_t dstlen, struct option_t* option);
+ int (*opt_from_string) (struct option_t* dst, const char* val,
+ char* errbuf, ssize_t errlen);
+} FuncTable[] = {
+ { 0, NULL, NULL }, /* there's no DT_ type with 0 */
+ { DT_BOOL, bool_to_string, bool_from_string },
+ { DT_NUM, num_to_string, num_from_string },
+ { DT_STR, str_to_string, str_from_string },
+ { DT_PATH, str_to_string, path_from_string },
+ { DT_QUAD, quad_to_string, quad_from_string },
+ { DT_SORT, sort_to_string, sort_from_string },
+ { DT_RX, rx_to_string, rx_from_string },
+ { DT_MAGIC, magic_to_string, magic_from_string },
+ /* synonyms should be resolved already so we don't need this
+ * but must define it as DT_ is used for indexing */
+ { DT_SYN, NULL, NULL },
+ { DT_ADDR, addr_to_string, addr_from_string },
+ { DT_USER, user_to_string, user_from_string },
+ { DT_SYS, sys_to_string, NULL },
+};
+
+static void bool_to_string (char* dst, ssize_t dstlen,
+ struct option_t* option) {
+ snprintf (dst, dstlen, "%s=%s", option->option,
+ option (option->data) ? "yes" : "no");
+}