From: Pierre Habouzit Date: Sat, 9 Dec 2006 13:38:22 +0000 (+0100) Subject: very temporary work on the new generation of config parser. X-Git-Url: http://git.madism.org/?p=apps%2Fmadmutt.git;a=commitdiff_plain;h=964d019c57a55168e7219ab15b6a2596ff24683a very temporary work on the new generation of config parser. Signed-off-by: Pierre Habouzit --- diff --git a/Makefile.am b/Makefile.am index 919945d..66ec987 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/configure.ac b/configure.ac index 9162271..1187006 100644 --- a/configure.ac +++ b/configure.ac @@ -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 --- 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 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 index 0000000..b63ab9a --- /dev/null +++ b/rcparser.y @@ -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 index 0000000..2ad6aa2 --- /dev/null +++ b/rctokens.sh @@ -0,0 +1,138 @@ +#! /bin/sh -e + +die() { + echo "$@" 1>&2 + exit 2 +} + +do_hdr() { + cat < +#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