very temporary work on the new generation of config parser.
authorPierre Habouzit <madcoder@debian.org>
Sat, 9 Dec 2006 13:38:22 +0000 (14:38 +0100)
committerPierre Habouzit <madcoder@debian.org>
Sat, 9 Dec 2006 13:38:22 +0000 (14:38 +0100)
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Makefile.am
configure.ac
init.c
parse.h [new file with mode: 0644]
rcparser.y [new file with mode: 0644]
rctokens.sh [new file with mode: 0755]

index 919945d..66ec987 100644 (file)
@@ -8,13 +8,17 @@ if BUILD_NNTP
 NNTP_SUBDIR = nntp
 endif
 
-SUBDIRS = intl m4 po $(XXXXXXXXXXXX_doc) apidoc contrib \
+SUBDIRS = intl m4 po $(XXXXXXXXXXXX_doc) apidoc contrib tools \
          lib-mime lib-lib lib-mx lib-crypt lib-hash lib-sys lib-ui \
          pop imap $(NNTP_SUBDIR)
 
-BUILT_SOURCES = keymap_defs.h version.h charset.gperf
+BUILT_SOURCES = keymap_defs.h version.h charset.gperf rctokens.gperf rcparser.c rcparser.h
 DISTCLEANFILES = $(BUILT_SOURCES)
 
+rcparser.c rcparser.h: rcparser.y
+       $(top_builddir)/tools/lemon -s $<
+       touch rcparser.c rcparser.h
+
 bin_PROGRAMS = madmutt madmutt_dotlock pgpringng pgpewrapng smime_keysng
 madmutt_SOURCES = $(BUILT_SOURCES) \
        alias.c attach.c base64.c browser.c buffy.c charset.c commands.c \
@@ -93,6 +97,9 @@ LDADD = @LIBOBJS@ @LIBINTL@
 charset.gperf: charset.def
        sh $< > $@
 
+rctokens.gperf: rctokens.sh
+       sh $< > $@
+
 smime_keysng: $(srcdir)/smime_keys.pl
        cp $(srcdir)/smime_keys.pl smime_keysng
        chmod +x smime_keysng
index 9162271..1187006 100644 (file)
@@ -741,6 +741,7 @@ AC_OUTPUT(Makefile
           apidoc/Makefile apidoc/doxygen.cfg
           doc/Makefile doc/instdoc.sh
           contrib/Makefile
+          tools/Makefile
           lib-lib/Makefile
           lib-mime/Makefile
           lib-crypt/Makefile
diff --git a/init.c b/init.c
index da7227d..c86f23e 100644 (file)
--- a/init.c
+++ b/init.c
@@ -2304,6 +2304,9 @@ static int mutt_execute_commands (string_list_t * p)
   return 0;
 }
 
+#include "parse.h"
+#include "rcparser.h"
+
 void mutt_init (int skip_sys_rc, string_list_t * commands)
 {
   struct passwd *pw;
@@ -2516,6 +2519,33 @@ void mutt_init (int skip_sys_rc, string_list_t * commands)
     }
   }
 
+#if 0
+  {
+    void *parser = ParseAlloc(malloc);
+    segment s1 = {" ", 1};
+    segment s2 = {"toto", 4 };
+    segment s3 = {"titi", 4 };
+    segment s4 = {"\"", 1 };
+
+    mutt_endwin(NULL);
+
+    ParseTrace(stderr, "> ");
+    Parse(parser, RCTK_ALT_ORDER, s1);
+    Parse(parser, RCTK_SPACE, s1);
+    Parse(parser, RCTK_ATOM, s2);
+    Parse(parser, RCTK_SPACE, s1);
+    Parse(parser, RCTK_DQUOTE, s4);
+    Parse(parser, RCTK_ATOM, s3);
+    Parse(parser, RCTK_SPACE, s1);
+    Parse(parser, RCTK_ATOM, s3);
+    Parse(parser, RCTK_DQUOTE, s4);
+    Parse(parser, RCTK_NL, s1);
+    Parse(parser, 0, s1);
+
+    exit(0);
+  }
+#endif
+
   /* Read the user's initialization file.  */
   if (access (Muttrc, F_OK) != -1) {
     if (!option (OPTNOCURSES))
diff --git a/parse.h b/parse.h
new file mode 100644 (file)
index 0000000..214fb60
--- /dev/null
+++ b/parse.h
@@ -0,0 +1,21 @@
+#ifndef MUTT_PARSE_H
+#define MUTT_PARSE_H
+
+typedef struct segment {
+    const char *s;
+    ssize_t len;
+} segment;
+
+#ifdef NDEBUG
+#  define ParseTrace(a, b)
+#else
+void ParseTrace(FILE *, char *);
+#endif
+
+const char *ParseTokenName(int);
+void *ParseAlloc(void *(*)(size_t));
+void ParseFree(void*, void (*)(void*));
+
+void Parse(void *, int, segment);
+
+#endif
diff --git a/rcparser.y b/rcparser.y
new file mode 100644 (file)
index 0000000..b63ab9a
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ *
+ *  Copyright © 2006 Pierre Habouzit
+ */
+
+%include {
+#   include "mutt.h"
+#   include "parse.h"
+
+    static buffer_t *buffer_merge(buffer_t *A, buffer_t **B)
+    {
+        buffer_addbuf(A, *B);
+        buffer_delete(B);
+        return A;
+    }
+
+    static inline int to_control(int c) {
+        return (toupper((unsigned char)c) - 'A' + 1) & 0x7f;
+    }
+
+    static buffer_t *buffer_escape(buffer_t *buf, const char *s, ssize_t len)
+    {
+        assert (len > 0);
+
+        switch (*s) {
+          case 'c': case 'C':
+            if (len < 2)
+                break;
+            buffer_addch(buf, to_control(s[1]));
+            buffer_add(buf, s + 2, len - 2);
+            return buf;
+
+          case 'x':
+            if (len >= 3) {
+                int i = (hexval(s[1]) << 4) | hexval(s[2]);
+                if (i >= 0) {
+                    buffer_addch(buf, i);
+                    buffer_add(buf, s + 3, len - 3);
+                    return buf;
+                }
+            }
+            break;
+
+          case '0': case '1': case '2': case '3':
+            if (len >= 3) {
+                int i = (octval(s[0]) << 6) | (octval(s[1]) << 3) | octval(s[2]);
+                if (i >= 0) {
+                    buffer_addch(buf, i);
+                    buffer_add(buf, s + 3, len - 3);
+                    return buf;
+                }
+            }
+            break;
+
+          case 'e': buffer_addch(buf, '\e'); return buf;
+          case 'f': buffer_addch(buf, '\f'); return buf;
+          case 'n': buffer_addch(buf, '\n'); return buf;
+          case 'r': buffer_addch(buf, '\r'); return buf;
+          case 't': buffer_addch(buf, '\t'); return buf;
+          case 'v': buffer_addch(buf, '\v'); return buf;
+
+          default:
+            break;
+        }
+
+        buffer_add(buf, s, len);
+        return buf;
+    }
+}
+
+%token_prefix RCTK_
+%token_type  { segment }
+%start_symbol rc
+
+/****************************************************************************/
+/* Often used                                                               */
+/****************************************************************************/
+
+spaces ::= SPACE .
+spaces ::= spaces SPACE .
+
+non_nl ::= ATOM|SPACE|BANG|BQUOTE|BSLASH|SHARP|DOLLAR|DQUOTE|EQUAL|LBRACE|PIPE|QUOTE|RBRACE|TILDE .
+non_nl_star ::= .
+non_nl_star ::= non_nl_star non_nl .
+
+to_eol ::= NL .
+to_eol ::= SHARP non_nl_star NL .
+to_eol ::= spaces SHARP non_nl_star NL .
+
+
+/****************************************************************************/
+/* Our macro tokens                                                         */
+/****************************************************************************/
+
+%type sqtok { buffer_t* }
+sqtok(C) ::= .                                 { C = buffer_new(); }
+sqtok(C) ::= sqtok(A) BSLASH BSLASH|QUOTE(B) . { buffer_addch(C = A, *B.s); }
+sqtok(C) ::= sqtok(A) BSLASH ATOM|SPACE|BANG|BQUOTE|SHARP|DOLLAR|DQUOTE|EQUAL|LBRACE|PIPE|RBRACE|TILDE(B) . {
+    buffer_addch(C = A, '\\');
+    buffer_add(C, B.s, B.len);
+}
+sqtok(C) ::= sqtok(A) ATOM|SPACE|BANG|BQUOTE|SHARP|DOLLAR|DQUOTE|EQUAL|LBRACE|PIPE|RBRACE|TILDE(B) . {
+    buffer_add(C = A, B.s, B.len);
+}
+
+%type dqtok { buffer_t* }
+dqtok(C) ::= .                           { C = buffer_new(); }
+dqtok(C) ::= dqtok(A) BSLASH non_nl(T) . { C = buffer_escape(A, T.s, T.len); }
+dqtok(C) ::= dqtok(A) ATOM|SPACE|BANG|SHARP|EQUAL|LBRACE|PIPE|RBRACE|TILDE(T)  . {
+    buffer_add(C = A, T.s, T.len);
+}
+
+%type tok   { buffer_t* }
+tok(R) ::= ATOM|BANG|EQUAL|PIPE|TILDE(T) . {
+    R = buffer_new();
+    buffer_add(R, T.s, T.len);
+}
+tok(R) ::= BSLASH non_nl(T) .          { R = buffer_new(); buffer_add(R, T.s, T.len); }
+tok(R) ::= QUOTE  sqtok(T) QUOTE .     { R = T; }
+tok(R) ::= DQUOTE dqtok(T) DQUOTE .    { R = T; }
+
+%type token_acc { buffer_t* }
+token_acc(A) ::= tok(T) . { A = T; }
+token_acc(C) ::= token_acc(A) tok(B) . { C = buffer_merge(A, &B); }
+
+%type token { buffer_t* }
+token(R) ::= spaces token_acc(T) . { R = T; }
+
+
+/****************************************************************************/
+/* list of tokens                                                           */
+/****************************************************************************/
+
+%type simple_list { string_list_t * }
+simple_list    ::= .
+simple_list(L) ::= simple_list(A) token(B) . {
+    string_list_t **last = string_list_last(&A);
+    *last = string_item_new();
+    (*last)->data = buffer_unwrap(&B);
+    L = A;
+}
+
+
+/****************************************************************************/
+/* Entry point : the rc lines                                               */
+/****************************************************************************/
+
+rc ::= rclines .
+rclines ::= .
+rclines ::= rclines rcline .
+
+rcline ::= to_eol .
+rcline ::= ALT_ORDER simple_list(L) to_eol . {
+    string_list_append(&AlternativeOrderList, L);
+}
+
+
+/* vim: set indentexpr= cin: */
diff --git a/rctokens.sh b/rctokens.sh
new file mode 100755 (executable)
index 0000000..2ad6aa2
--- /dev/null
@@ -0,0 +1,138 @@
+#! /bin/sh -e
+
+die() {
+    echo "$@" 1>&2
+    exit 2
+}
+
+do_hdr() {
+    cat <<EOF
+/*
+ *  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, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ *  MA 02110-1301, USA.
+ *
+ *  Copyright © 2006 Pierre Habouzit
+ */
+
+/*****     THIS FILE IS AUTOGENERATED DO NOT MODIFY DIRECTLY !    *****/
+
+EOF
+}
+
+do_tokens() {
+    while read tok; do
+        echo "$tok, RCTK_`echo $tok | tr 'a-z-' 'A-Z_'`"
+    done
+}
+
+do_c() {
+    cat <<EOF | gperf --ignore-case -m16 -l -t -C -F",0" -Nrc_which_token_aux
+%{
+`do_hdr`
+
+#include <lib-lib/lib-lib.h>
+#include "rctoken.h"
+
+static const struct tok *
+rc_which_token_aux(const char *str, unsigned int len);
+
+%}
+struct tok { const char *name; int val; };
+%%
+`do_tokens`
+%%
+
+static int rc_which_token(const char *s, ssize_t len)
+{
+    if (len < 0)
+        len = m_strlen(s);
+
+    if (len) {
+        const struct tok *res = rc_which_token_aux(s, len);
+        return res ? res->val : -1;
+    } else {
+        return -1;
+    }
+}
+EOF
+}
+
+trap "rm -f $1" 1 2 3 15
+grep '^### ' < $0 | cut -d' ' -f2 | do_c
+
+exit 0
+
+#****************************************************************************#
+#                          muttrc tokens list                                #
+#****************************************************************************#
+### account-hook
+### alias
+### alternates
+### alternative_order
+### append-hook
+### attachments
+### auto_view
+### bind
+### charset-hook
+### close-hook
+### color
+### exec
+### fcc-hook
+### fcc-save-hook
+### folder-hook
+### hdr_order
+### open-hook
+### unalternates
+### unattachments
+### uncolor
+### iconv-hook
+### crypt-hook
+### ignore
+### lists
+### macro
+### mailboxes
+### mbox-hook
+### message-hook
+### mime_lookup
+### mono
+### my_hdr
+### nospam
+### pgp-hook
+### push
+### reply-hook
+### reset
+### save-hook
+### score
+### send2-hook
+### send-hook
+### set
+### source
+### spam
+### subscribe
+### toggle
+### unalias
+### unalternative_order
+### unauto_view
+### unhdr_order
+### unhook
+### unignore
+### unlists
+### unmailboxes
+### unmime_lookup
+### unmono
+### unmy_hdr
+### unscore
+### unset
+### unsubscribe