convert {charset,iconv}-hooks.
authorPierre Habouzit <madcoder@debian.org>
Tue, 27 Mar 2007 23:42:17 +0000 (01:42 +0200)
committerPierre Habouzit <madcoder@debian.org>
Tue, 27 Mar 2007 23:42:17 +0000 (01:42 +0200)
They even gain regex-capture for free \o/
Use it that way (for now):

    MCharset.charset_hook("^windows-([0-9]*)$", "cp%1")

Isn't _that_ cute ?

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
charset.cpkg
hook.c
init.h
lib-lib/rx.c
lib-lib/rx.h
mutt.h
protos.h
tools/cpkg2c.mll

index 3db2745..1ac8cea 100644 (file)
@@ -38,6 +38,9 @@
 #endif
 @import "lib-lua/base.cpkg"
 
+static rx_t *charset_hooks = NULL;
+static rx_t *iconv_hooks   = NULL;
+
 @package MCharset {
     /*
      ** .pp
      ** instead of or after \fTiso-8859-1\fP.
      */
     string_t send_charset    = m_strdup("us-ascii:iso-8859-1:utf-8");
+
+    void charset_hook(rx_t local, const string_t alias) {
+        rx_set_template(local, alias);
+        rx_list_append(&charset_hooks, local);
+    };
+
+    void iconv_hook(rx_t local, const string_t alias) {
+        rx_set_template(local, alias);
+        rx_list_append(&iconv_hooks, local);
+    };
 };
 
 int Charset_is_utf8 = 0;
@@ -191,34 +204,37 @@ int charset_is_us_ascii(const char *s)
 /* Like iconv_open, but canonicalises the charsets */
 iconv_t mutt_iconv_open(const char *tocode, const char *fromcode, int flags)
 {
-    char tocode1[STRING];
-    char fromcode1[STRING];
-    const char *tmp;
-
+    char to1[STRING];
+    char from1[STRING];
+    char tmp[STRING];
     iconv_t cd;
 
-    if ((flags & M_ICONV_HOOK_TO) && (tmp = mutt_charset_hook(tocode1))) {
-        charset_canonicalize(tocode1, sizeof(tocode1), tmp);
+    if ((flags & M_ICONV_HOOK_TO)
+    &&  rx_list_match2(charset_hooks, tocode, tmp, sizeof(tmp))) {
+        charset_canonicalize(to1, sizeof(to1), tmp);
     } else {
-        charset_canonicalize(tocode1, sizeof(tocode1), tocode);
+        charset_canonicalize(to1, sizeof(to1), tocode);
     }
 
-    if ((flags & M_ICONV_HOOK_FROM) && (tmp = mutt_charset_hook(fromcode1))) {
-        charset_canonicalize(fromcode1, sizeof(fromcode1), tmp);
+    if ((flags & M_ICONV_HOOK_FROM)
+    &&  rx_list_match2(charset_hooks, fromcode, tmp, sizeof(tmp))) {
+        charset_canonicalize(from1, sizeof(from1), tmp);
     } else {
-        charset_canonicalize(fromcode1, sizeof(fromcode1), fromcode);
+        charset_canonicalize(from1, sizeof(from1), fromcode);
     }
 
-    cd = iconv_open(tocode1, fromcode1);
-    if (cd != MUTT_ICONV_ERROR)
+    if ((cd = iconv_open(to1, from1)) != MUTT_ICONV_ERROR)
         return cd;
 
     {
-        const char *to = mutt_iconv_hook(tocode1);
-        const char *from = mutt_iconv_hook(fromcode1);
+        char to2[STRING];
+        char from2[STRING];
 
-        return to && from ? iconv_open(to, from) : MUTT_ICONV_ERROR;
+        if (rx_list_match2(iconv_hooks, to1, to2, sizeof(to2))
+        &&  rx_list_match2(iconv_hooks, from1, from2, sizeof(from2)))
+            return iconv_open(to2, from2);
     }
+    return MUTT_ICONV_ERROR;
 }
 
 
diff --git a/hook.c b/hook.c
index b81b9c8..0a8cc51 100644 (file)
--- a/hook.c
+++ b/hook.c
@@ -88,8 +88,7 @@ int mutt_parse_hook (BUFFER * buf __attribute__ ((unused)), BUFFER * s,
       return (-1);
     }
   }
-  else if (DefaultHook && !(data & (M_CHARSETHOOK | M_ACCOUNTHOOK))
-           && !(data & M_CRYPTHOOK))
+  else if (DefaultHook && !(data & M_ACCOUNTHOOK) && !(data & M_CRYPTHOOK))
   {
     char tmp[HUGE_STRING];
 
@@ -152,22 +151,15 @@ int mutt_parse_hook (BUFFER * buf __attribute__ ((unused)), BUFFER * s,
   else {
     rx = p_new(regex_t, 1);
 #ifdef M_CRYPTHOOK
-    if ((rc =
-         REGCOMP (rx, NONULL (pattern.data),
-                  ((data & (M_CRYPTHOOK | M_CHARSETHOOK)) ? REG_ICASE : 0)))
-        != 0)
-#else
-    if ((rc =
-         REGCOMP (rx, NONULL (pattern.data),
-                  (data & (M_CHARSETHOOK | M_ICONVHOOK)) ? REG_ICASE : 0)) !=
-        0)
-#endif /* M_CRYPTHOOK */
+    if ((rc = REGCOMP(rx, NONULL(pattern.data),
+                  ((data & M_CRYPTHOOK) ? REG_ICASE : 0))) != 0)
     {
       regerror (rc, rx, err->data, err->dsize);
       regfree (rx);
       p_delete(&rx);
       goto error;
     }
+#endif /* M_CRYPTHOOK */
   }
 
   if (ptr) {
@@ -384,16 +376,6 @@ static const char *_mutt_string_hook (const char *match, int hook)
   return (NULL);
 }
 
-const char *mutt_charset_hook (const char *chs)
-{
-  return _mutt_string_hook (chs, M_CHARSETHOOK);
-}
-
-const char *mutt_iconv_hook (const char *chs)
-{
-  return _mutt_string_hook (chs, M_ICONVHOOK);
-}
-
 const char *mutt_crypt_hook (address_t * adr)
 {
   return _mutt_string_hook (adr->mailbox, M_CRYPTHOOK);
diff --git a/init.h b/init.h
index 624e72e..9d6b533 100644 (file)
--- a/init.h
+++ b/init.h
@@ -3458,15 +3458,11 @@ struct command_t Commands[] = {
     {"exec",                mutt_parse_exec,       0},
     {"account-hook",        mutt_parse_hook,       M_ACCOUNTHOOK},
     {"append-hook",         mutt_parse_hook,       M_APPENDHOOK},
-    {"charset-hook",        mutt_parse_hook,       M_CHARSETHOOK},
     {"close-hook",          mutt_parse_hook,       M_CLOSEHOOK},
     {"crypt-hook",          mutt_parse_hook,       M_CRYPTHOOK},
     {"fcc-hook",            mutt_parse_hook,       M_FCCHOOK},
     {"fcc-save-hook",       mutt_parse_hook,       M_FCCHOOK|M_SAVEHOOK},
     {"folder-hook",         mutt_parse_hook,       M_FOLDERHOOK},
-#ifdef HAVE_ICONV
-    {"iconv-hook",          mutt_parse_hook,       M_ICONVHOOK},
-#endif
     {"mbox-hook",           mutt_parse_hook,       M_MBOXHOOK},
     {"message-hook",        mutt_parse_hook,       M_MESSAGEHOOK},
     {"open-hook",           mutt_parse_hook,       M_OPENHOOK},
index 02a01d0..79ec5b8 100644 (file)
@@ -57,7 +57,7 @@ void rx_set_template(rx_t *rx, const char *tpl)
 {
     const char *p = tpl;
 
-    m_strreplace(&rx->template, tpl);
+    m_strreplace(&rx->tpl, tpl);
     rx->nmatch = 0;
 
     while ((p = strchr(p, '%'))) {
@@ -78,7 +78,7 @@ void rx_wipe(rx_t *rx)
     p_delete(&rx->pattern);
     regfree(rx->rx);
     p_delete(&rx->rx);
-    p_delete(&rx->template);
+    p_delete(&rx->tpl);
 }
 
 int rx_list_match(rx_t *l, const char *s)
@@ -112,7 +112,7 @@ int rx_list_match2(rx_t *l, const char *s, char *dst, int dlen)
 
         if (regexec(l->rx, s, l->nmatch, pmatch, 0) == 0) {
             /* Copy template into dst, with substitutions. */
-            const char *p = l->template, *q;
+            const char *p = l->tpl, *q;
 
             for (q = strchr(p, '%'); q; q = strchr(p + 1, '%')) {
                 int n;
index 3b57168..81352ad 100644 (file)
@@ -45,7 +45,7 @@ typedef struct rx_t {
     int not;                      /* do not match */
 
     int nmatch;                   /* nb matches */
-    char *template;               /* out template */
+    char *tpl;                    /* out template */
 } rx_t;
 
 rx_t *rx_compile(const char*, int);
diff --git a/mutt.h b/mutt.h
index 82ab163..336ebe1 100644 (file)
--- a/mutt.h
+++ b/mutt.h
@@ -37,17 +37,15 @@ typedef struct {
 #define M_SENDHOOK     (1<<2)
 #define M_FCCHOOK      (1<<3)
 #define M_SAVEHOOK     (1<<4)
-#define M_CHARSETHOOK  (1<<5)
-#define M_ICONVHOOK    (1<<6)
-#define M_MESSAGEHOOK  (1<<7)
-#define M_CRYPTHOOK    (1<<8)
-#define M_ACCOUNTHOOK  (1<<9)
-#define M_REPLYHOOK    (1<<10)
-#define M_SEND2HOOK     (1<<11)
-
-#define M_OPENHOOK     (1<<12)
-#define M_APPENDHOOK   (1<<13)
-#define M_CLOSEHOOK    (1<<14)
+#define M_MESSAGEHOOK  (1<<5)
+#define M_CRYPTHOOK    (1<<6)
+#define M_ACCOUNTHOOK  (1<<7)
+#define M_REPLYHOOK    (1<<8)
+#define M_SEND2HOOK     (1<<9)
+
+#define M_OPENHOOK     (1<<10)
+#define M_APPENDHOOK   (1<<11)
+#define M_CLOSEHOOK    (1<<12)
 
 /* tree characters for linearize_tree and print_enriched_string */
 #define M_TREE_LLCORNER                1
index ce7e380..376128f 100644 (file)
--- a/protos.h
+++ b/protos.h
@@ -35,9 +35,6 @@ int mutt_cmp_header (const HEADER*, const HEADER*);
 
 int is_from (const char *, char *, ssize_t, time_t *);
 
-const char *mutt_charset_hook (const char *);
-const char *mutt_iconv_hook (const char *);
-
 ssize_t _mutt_expand_path(char *, ssize_t, const char *, int);
 #define mutt_expand_path(s, n) _mutt_expand_path((s), (n), (s), 0)
 
index 8355199..8b3105d 100644 (file)
 
   let put_line = printf "#line %d \"%s\"\n"
 
+  let isspace = function |' '|'\t' -> true | _ -> false
+
+  let strip s =
+    let l = ref 0 and r = ref (String.length s) in
+    while (isspace s.[!l]     && !l < !r) do incr l done;
+    while (isspace s.[!r - 1] && !l < !r) do decr r done;
+    String.sub s !l (!r - !l)
+
 (* @types related {{{ *)
 
   type typedef =
@@ -91,9 +99,9 @@
       | [t]          -> (false, type_find lpos fpos t)
       | _ -> assert false
     in
-    match s with
+    match strip s with
     | "void" -> []
-    | s      -> List.map aux (Str.split (Str.regexp "[ \t]+,[ \t]+") s)
+    | s      -> List.map aux (Str.split (Str.regexp "[ \t]*,[ \t]*") s)
 
   let parse_args lpos fpos s =
     let aux t =
       | [t; n]          -> ((false, type_find lpos fpos t), n)
       | _ -> assert false
     in
-    match s with
+    match strip s with
     | "void" -> []
-    | s      -> List.map aux (Str.split (Str.regexp "[ \t]+,[ \t]+") s)
+    | s      -> List.map aux (Str.split (Str.regexp "[ \t]*,[ \t]*") s)
 
 (* }}} *)
 (* parsing helpers {{{ *)