DT_RX,
DT_MAGIC,
DT_SYN,
- DT_ADDR
+ DT_ADDR,
+ DT_MBCHARTBL
};
struct
{ "DT_MAGIC", "folder magic" },
{ "DT_SYN", NULL },
{ "DT_ADDR", "e-mail address" },
+ { "DT_MBCHARTBL", "string" },
{ NULL, NULL }
};
case DT_RX:
case DT_ADDR:
case DT_PATH:
+ case DT_MBCHARTBL:
{
if (!strcmp (s, "0"))
break;
/* configuration file */
case F_CONF:
{
- if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH)
+ if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH ||
+ type == DT_MBCHARTBL)
{
fprintf (out, "\n# set %s=\"", varname);
conf_print_strval (val, out);
fprintf (out, "\n#\n# Name: %s", varname);
fprintf (out, "\n# Type: %s", type2human (type));
- if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH)
+ if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH ||
+ type == DT_MBCHARTBL)
{
fputs ("\n# Default: \"", out);
conf_print_strval (val, out);
fprintf (out, "\n.TP\n.B %s\n", varname);
fputs (".nf\n", out);
fprintf (out, "Type: %s\n", type2human (type));
- if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH)
+ if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH ||
+ type == DT_MBCHARTBL)
{
fputs ("Default: \\(lq", out);
man_print_strval (val, out);
fprintf (out, "</title>\n<literallayout>Type: %s", type2human (type));
- if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH)
+ if (type == DT_STR || type == DT_RX || type == DT_ADDR || type == DT_PATH ||
+ type == DT_MBCHARTBL)
{
if (val && *val)
{
}
}
+static void free_mbchar_table (mbchar_table **t)
+{
+ if (!t || !*t)
+ return;
+
+ FREE (&(*t)->chars);
+ FREE (&(*t)->segmented_str);
+ FREE (&(*t)->orig_str);
+ FREE (t); /* __FREE_CHECKED__ */
+}
+
+static mbchar_table *parse_mbchar_table (const char *s)
+{
+ mbchar_table *t;
+ size_t slen, k;
+ mbstate_t mbstate;
+ char *d;
+
+ t = safe_calloc (1, sizeof (mbchar_table));
+ slen = mutt_strlen (s);
+ if (!slen)
+ return t;
+
+ t->orig_str = safe_strdup (s);
+ /* This could be more space efficient. However, being used on tiny
+ * strings (Tochars and StChars), the overhead is not great. */
+ t->chars = safe_calloc (slen, sizeof (char *));
+ d = t->segmented_str = safe_calloc (slen * 2, sizeof (char));
+
+ memset (&mbstate, 0, sizeof (mbstate));
+ while (slen && (k = mbrtowc (NULL, s, slen, &mbstate)))
+ {
+ if (k == (size_t)(-1) || k == (size_t)(-2))
+ {
+ dprint (1, (debugfile,
+ "parse_mbchar_table: mbrtowc returned %d converting %s in %s\n",
+ (k == (size_t)(-1)) ? -1 : -2,
+ s, t->orig_str));
+ if (k == (size_t)(-1))
+ memset (&mbstate, 0, sizeof (mbstate));
+ k = (k == (size_t)(-1)) ? 1 : slen;
+ }
+
+ slen -= k;
+ t->chars[t->len++] = d;
+ while (k--)
+ *d++ = *s++;
+ *d++ = '\0';
+ }
+
+ return t;
+}
+
static int parse_unignore (BUFFER *buf, BUFFER *s, unsigned long data, BUFFER *err)
{
do
case DT_STR:
mutt_str_replace ((char **) p->data, (char *) p->init);
break;
+ case DT_MBCHARTBL:
+ free_mbchar_table ((mbchar_table **)p->data);
+ *((mbchar_table **) p->data) = parse_mbchar_table ((char *) p->init);
+ break;
case DT_PATH:
FREE((char **) p->data); /* __FREE_CHECKED__ */
if (p->init)
}
else if (myvar || DTYPE (MuttVars[idx].type) == DT_STR ||
DTYPE (MuttVars[idx].type) == DT_PATH ||
- DTYPE (MuttVars[idx].type) == DT_ADDR)
+ DTYPE (MuttVars[idx].type) == DT_ADDR ||
+ DTYPE (MuttVars[idx].type) == DT_MBCHARTBL)
{
if (unset)
{
myvar_del (myvar);
else if (DTYPE (MuttVars[idx].type) == DT_ADDR)
rfc822_free_address ((ADDRESS **) MuttVars[idx].data);
+ else if (DTYPE (MuttVars[idx].type) == DT_MBCHARTBL)
+ free_mbchar_table ((mbchar_table **) MuttVars[idx].data);
else
/* MuttVars[idx].data is already 'char**' (or some 'void**') or...
* so cast to 'void*' is okay */
mutt_pretty_mailbox (_tmp, sizeof (_tmp));
val = _tmp;
}
+ else if (DTYPE (MuttVars[idx].type) == DT_MBCHARTBL)
+ {
+ mbchar_table *mbt = (*((mbchar_table **) MuttVars[idx].data));
+ val = mbt ? NONULL (mbt->orig_str) : "";
+ }
else
val = *((char **) MuttVars[idx].data);
if (mutt_strcmp (MuttVars[idx].option, "charset") == 0)
mutt_set_charset (Charset);
}
+ else if (DTYPE (MuttVars[idx].type) == DT_MBCHARTBL)
+ {
+ free_mbchar_table ((mbchar_table **) MuttVars[idx].data);
+ *((mbchar_table **) MuttVars[idx].data) = parse_mbchar_table (tmp->data);
+ }
else
{
rfc822_free_address ((ADDRESS **) MuttVars[idx].data);
if (DTYPE (MuttVars[idx].type) == DT_PATH)
mutt_pretty_mailbox (tmp, sizeof (tmp));
}
+ else if (DTYPE (MuttVars[idx].type) == DT_MBCHARTBL)
+ {
+ mbchar_table *mbt = (*((mbchar_table **) MuttVars[idx].data));
+ strfcpy (tmp, mbt ? NONULL (mbt->orig_str) : "", sizeof (tmp));
+ }
else if (DTYPE (MuttVars[idx].type) == DT_ADDR)
{
rfc822_write_address (tmp, sizeof (tmp), *((ADDRESS **) MuttVars[idx].data), 0);