2006-06-12 [wwp] 2.3.0cvs2
authorTristan Chabredier <wwp@claws-mail.org>
Mon, 12 Jun 2006 15:59:35 +0000 (15:59 +0000)
committerTristan Chabredier <wwp@claws-mail.org>
Mon, 12 Jun 2006 15:59:35 +0000 (15:59 +0000)
* src/quote_fmt.c
* src/quote_fmt_lex.l
* src/quote_fmt_parse.y
extend the quote_fmt parser (templates and quotes):
- allow limited sub-expressions in |p{} and |f{} expressions,
- add !x{expr} (evaluate and insert 'expr' if 'x' is not set) and \! symbols,
- implemented/fixed missing implementation of query_references and show_references,
- completed, fixed contents and format of the symbols help dialog,
- fix some compilation warnings.

ChangeLog
PATCHSETS
configure.ac
src/quote_fmt.c
src/quote_fmt_lex.l
src/quote_fmt_parse.y

index 9bdc43ddedc78fd57f99d3f4bc02a4043d4ab935..4a7b9acaf716c4d9d9d510493833a78cff1479f7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2006-06-12 [wwp]       2.3.0cvs2
+
+       * src/quote_fmt.c
+       * src/quote_fmt_lex.l
+       * src/quote_fmt_parse.y
+               extend the quote_fmt parser (templates and quotes):
+               - allow limited sub-expressions in |p{} and |f{} expressions,
+               - add !x{expr} (evaluate and insert 'expr' if 'x' is not set) and \! symbols,
+               - implemented/fixed missing implementation of query_references and show_references,
+               - completed, fixed contents and format of the symbols help dialog,
+               - fix some compilation warnings.
+
 2006-06-12 [wwp]       2.3.0cvs1
 
        * manual/advanced.xml
index fea0898c9967dfe7bc8f89df5c2879ec95f8c73d..5f47bb2ab500db0bbd1666ef8d1314318a8b5abb 100644 (file)
--- a/PATCHSETS
+++ b/PATCHSETS
 ( cvs diff -u -r 1.28.2.16 -r 1.28.2.17 src/mbox.c;  ) > 2.2.3cvs13.patchset
 ( cvs diff -u -r 1.1.2.8 -r 1.1.2.9 po/ca.po;  cvs diff -u -r 1.9.2.6 -r 1.9.2.7 po/cs.po;  cvs diff -u -r 1.58.2.22 -r 1.58.2.23 po/de.po;  cvs diff -u -r 1.9.2.5 -r 1.9.2.6 po/el.po;  cvs diff -u -r 1.42.2.24 -r 1.42.2.25 po/fr.po;  cvs diff -u -r 1.34.2.18 -r 1.34.2.19 po/it.po;  cvs diff -u -r 1.50.2.18 -r 1.50.2.19 po/pt_BR.po;  cvs diff -u -r 1.17.2.21 -r 1.17.2.22 po/sr.po;  cvs diff -u -r 1.5.2.15 -r 1.5.2.16 po/zh_CN.po;  ) > 2.2.3cvs14.patchset
 ( cvs diff -u -r 1.1.2.19 -r 1.1.2.20 manual/advanced.xml;  cvs diff -u -r 1.1.2.10 -r 1.1.2.11 manual/fr/advanced.xml;  ) > 2.3.0cvs1.patchset
+( cvs diff -u -r 1.8.2.6 -r 1.8.2.7 src/quote_fmt.c;  cvs diff -u -r 1.8.2.2 -r 1.8.2.3 src/quote_fmt_lex.l;  cvs diff -u -r 1.22.2.20 -r 1.22.2.21 src/quote_fmt_parse.y;  ) > 2.3.0cvs2.patchset
index 6e4e7aded2cf3a1737e744d8978be9e3542e8624..d577f31f01d0a25c7ea55e42a16d01b586bbe3c9 100644 (file)
@@ -11,7 +11,7 @@ MINOR_VERSION=3
 MICRO_VERSION=0
 INTERFACE_AGE=0
 BINARY_AGE=0
-EXTRA_VERSION=1
+EXTRA_VERSION=2
 EXTRA_RELEASE=
 EXTRA_GTK2_VERSION=
 
index e974c88bc5b3718abcc79ad1791b73b81dacf11b..881f7be08c2f5a816e976f358f0c5fff3ba2ca46 100644 (file)
@@ -37,7 +37,7 @@
  * When adding new lines, remember to put 2 strings for each line
  */
 static gchar *quote_desc_strings[] = {
-       "%D{fmt}",      N_("customized date format (see man strftime)"), /* date expression */
+       "%D{fmt}",      N_("customized date format (see 'man strftime')"), /* date expression */
        "%d",           N_("Date"), /* date */
        "%f",           N_("From"), /* from */
        "%N",           N_("full name of sender"), /* full name */
@@ -55,18 +55,24 @@ static gchar *quote_desc_strings[] = {
        "%m",           N_("message body without signature"), /* message with no signature */
        "%q",           N_("quoted message body without signature"), /* quoted message with no signature */
        "%X",           N_("cursor position"), /* X marks the cursor spot */
-       "",             NULL,
-       "?x{expr}",     N_("insert expr if x is set\nx is one of the characters above after %"),
-       "",             NULL,
        "\\%",          N_("literal %"),
        "\\\\",         N_("literal backslash"),
        "\\?",          N_("literal question mark"),
+       "\\!",          N_("literal exclamation mark"),
        "\\|",          N_("literal pipe"),
        "\\{",          N_("literal opening curly brace"),
        "\\}",          N_("literal closing curly brace"),
+       "\\t",          N_("tab"),
+       "\\n",          N_("linefeed"),
+       "",             NULL,
+       "?x{expr}\n",   N_("insert expr if x is set\n(where x is one of the dfNFLIstcnri characters)"),
+       "!x{expr}\n",   N_("insert expr if x is not set\n(where x is one of the dfNFLIstcnri characters)"),
+       "|f{sub_expr}\n",       N_("insert file:\nsub_expr is evaluated as a filename to insert"), /* insert file */
+       "|p{sub_expr}\n\n",     N_("insert program output:\nsub_expr is evaluated as a command-line to get\nthe output from"), /* insert program output */
        "",             NULL,
-       "|f{file}",     N_("insert file"),
-       "|p{command}",  N_("insert program output"), /* insert program output */
+       "terms definition:",    NULL,
+       "expr",                 "text that can contain any of the symbols above",
+       "sub_expr\n",   "text that can contain any of the symbols above\nbut ?x{}, !x{}, |f{} and |p{}",
        NULL,NULL
 };
 
index 04975d63ee4877667fbd64b4fe119f70676e5f9a..844fefb08f7ad76a56610899113e72e023f26d61 100644 (file)
@@ -72,12 +72,13 @@ int quote_fmt_firsttime = 1;
 "\\t"|"\t" /* tab */ return SHOW_TAB;
 "\\n"|"\n" /* return */ return SHOW_EOL;
 "\\?" /* ? */ return SHOW_QUESTION_MARK;
+"\\!" return SHOW_EXCLAMATION_MARK;
 "\\|" return SHOW_PIPE;
 "\\{" return SHOW_OPARENT;
 "\\}" return SHOW_CPARENT;
 "?d" /* query date */ return QUERY_DATE;
 "?f" /* query from */ return QUERY_FROM;
-"?N"|"?F"|"?I" /* query from name */ return QUERY_FULLNAME;
+"?N"|"?F"|"?L"|"?I" /* query from name */ return QUERY_FULLNAME;
 "?s" /* query subject */ return QUERY_SUBJECT;
 "?t" /* query to */ return QUERY_TO;
 "?c" /* query cc */ return QUERY_CC;
@@ -86,6 +87,15 @@ int quote_fmt_firsttime = 1;
 "?r" /* query references */ return QUERY_REFERENCES;
 "|f" /* insert file */ return INSERT_FILE;
 "|p" /* insert program output */ return INSERT_PROGRAMOUTPUT;
+"!d" /* query date */ return QUERY_NOT_DATE;
+"!f" /* query from */ return QUERY_NOT_FROM;
+"!N"|"!F"|"!L"|"!I" /* query from name */ return QUERY_NOT_FULLNAME;
+"!s" /* query subject */ return QUERY_NOT_SUBJECT;
+"!t" /* query to */ return QUERY_NOT_TO;
+"!c" /* query cc */ return QUERY_NOT_CC;
+"!n" /* query newsgroups */ return QUERY_NOT_NEWSGROUPS;
+"!i" /* query message-id */ return QUERY_MESSAGEID;
+"!r" /* query references */ return QUERY_REFERENCES;
 <S_DATE>"{" return OPARENT;
 <S_DATE>"}" { BEGIN S_NORMAL; return CPARENT; }
 <S_NORMAL>"{" return OPARENT;
index 3399ffc05b7496e304b68ccec0c14d8c97b9ad0e..ab0427e8f29b8ca78fb7068df39cf87d01a72751 100644 (file)
@@ -47,14 +47,22 @@ static gboolean dry_run = FALSE;
 static gint maxsize = 0;
 static gint stacksize = 0;
 
-static gchar *buffer = NULL;
-static gint bufmax = 0;
-static gint bufsize = 0;
+typedef struct st_buffer
+{
+       gchar *buffer;
+       gint bufsize;
+       gint bufmax;
+} st_buffer;
+
+static struct st_buffer main_expr = { NULL, 0, 0 };
+static struct st_buffer sub_expr = { NULL, 0, 0 };
+static struct st_buffer* current = NULL;
+
 static const gchar *quote_str = NULL;
 static const gchar *body = NULL;
 static gint error = 0;
 
-static gint cursor_pos  = -1;
+static gint cursor_pos = -1;
 
 extern int quote_fmt_firsttime;
 
@@ -74,30 +82,47 @@ static void add_visibility(gboolean val)
 static void remove_visibility(void)
 {
        stacksize--;
+       if (stacksize < 0) {
+               g_warning("Error: visibility stack underflow\n");
+               stacksize = 0;
+       }
 }
 
 static void add_buffer(const gchar *s)
 {
        gint len;
 
+       if (s == NULL)
+               return;
+
        len = strlen(s);
-       if (bufsize + len + 1 > bufmax) {
-               if (bufmax == 0)
-                       bufmax = 128;
-               while (bufsize + len + 1 > bufmax)
-                       bufmax *= 2;
-               buffer = g_realloc(buffer, bufmax);
-       }
-       strcpy(buffer + bufsize, s);
-       bufsize += len;
+       if (current->bufsize + len + 1 > current->bufmax) {
+               if (current->bufmax == 0)
+                       current->bufmax = 128;
+               while (current->bufsize + len + 1 > current->bufmax)
+                       current->bufmax *= 2;
+               current->buffer = g_realloc(current->buffer, current->bufmax);
+       }
+       strcpy(current->buffer + current->bufsize, s);
+       current->bufsize += len;
+}
+
+static void clear_buffer(void)
+{
+       if (current->buffer)
+               *current->buffer = '\0';
+       current->bufsize = 0;
 }
 
 gchar *quote_fmt_get_buffer(void)
 {
+       if (current != &main_expr)
+               g_warning("Error: parser still in sub-expr mode\n");
+
        if (error != 0)
                return NULL;
        else
-               return buffer;
+               return current->buffer;
 }
 
 gint quote_fmt_get_cursor_pos(void)
@@ -106,8 +131,8 @@ gint quote_fmt_get_cursor_pos(void)
 }
 
 #define INSERT(buf) \
-       if (stacksize != 0 && visible[stacksize - 1]) \
-               add_buffer(buf)
+       if (stacksize != 0 && visible[stacksize - 1])\
+               add_buffer(buf); \
 
 #define INSERT_CHARACTER(chr) \
        if (stacksize != 0 && visible[stacksize - 1]) { \
@@ -126,9 +151,10 @@ void quote_fmt_init(MsgInfo *info, const gchar *my_quote_str,
        dry_run = my_dry_run;
        stacksize = 0;
        add_visibility(TRUE);
-       if (buffer != NULL)
-               *buffer = 0;
-       bufsize = 0;
+       main_expr.bufmax = 0;
+       sub_expr.bufmax = 0;
+       current = &main_expr;
+       clear_buffer();
        error = 0;
         /*
          * force LEX initialization
@@ -243,14 +269,14 @@ static void quote_fmt_show_first_name(const MsgInfo *msginfo)
        if (!msginfo->fromname)
                return; 
        
-       p = strchr(msginfo->fromname, ',');
+       p = (guchar*)strchr(msginfo->fromname, ',');
        if (p != NULL) {
                /* fromname is like "Duck, Donald" */
                p++;
                while (*p && isspace(*p)) p++;
-               str = alloca(strlen(p) + 1);
+               str = alloca(strlen((char *)p) + 1);
                if (str != NULL) {
-                       strcpy(str, p);
+                       strcpy(str, (char *)p);
                        INSERT(str);
                }
        } else {
@@ -258,7 +284,7 @@ static void quote_fmt_show_first_name(const MsgInfo *msginfo)
                str = alloca(strlen(msginfo->fromname) + 1);
                if (str != NULL) {
                        strcpy(str, msginfo->fromname);
-                       p = str;
+                       p = (guchar *)str;
                        while (*p && !isspace(*p)) p++;
                        *p = '\0';
                        INSERT(str);
@@ -321,10 +347,10 @@ static void quote_fmt_show_sender_initial(const MsgInfo *msginfo)
        if (!msginfo->fromname) 
                return;
 
-       p = msginfo->fromname;
+       p = (guchar *)msginfo->fromname;
        cur = tmp;
        while (*p) {
-               if (*p && g_utf8_validate(p, 1, NULL)) {
+               if (*p && g_utf8_validate((gchar *)p, 1, NULL)) {
                        *cur = toupper(*p);
                                cur++;
                        len++;
@@ -416,10 +442,13 @@ static void quote_fmt_insert_program_output(const gchar *progname)
 %token SHOW_PERCENT SHOW_CC SHOW_REFERENCES SHOW_MESSAGE
 %token SHOW_QUOTED_MESSAGE SHOW_BACKSLASH SHOW_TAB
 %token SHOW_QUOTED_MESSAGE_NO_SIGNATURE SHOW_MESSAGE_NO_SIGNATURE
-%token SHOW_EOL SHOW_QUESTION_MARK SHOW_PIPE SHOW_OPARENT SHOW_CPARENT
+%token SHOW_EOL SHOW_QUESTION_MARK SHOW_EXCLAMATION_MARK SHOW_PIPE SHOW_OPARENT SHOW_CPARENT
 %token QUERY_DATE QUERY_FROM
 %token QUERY_FULLNAME QUERY_SUBJECT QUERY_TO QUERY_NEWSGROUPS
 %token QUERY_MESSAGEID QUERY_CC QUERY_REFERENCES
+%token QUERY_NOT_DATE QUERY_NOT_FROM
+%token QUERY_NOT_FULLNAME QUERY_NOT_SUBJECT QUERY_NOT_TO QUERY_NOT_NEWSGROUPS
+%token QUERY_NOT_MESSAGEID QUERY_NOT_CC QUERY_NOT_REFERENCES
 %token INSERT_FILE INSERT_PROGRAMOUTPUT
 %token OPARENT CPARENT
 %token CHARACTER
@@ -435,20 +464,31 @@ static void quote_fmt_insert_program_output(const gchar *progname)
 %%
 
 quote_fmt:
-       character_or_special_or_insert_or_query_list;
+       character_or_special_or_insert_or_query_list ;
+
+sub_expr:
+       character_or_special_list ;
 
 character_or_special_or_insert_or_query_list:
        character_or_special_or_insert_or_query character_or_special_or_insert_or_query_list
        | character_or_special_or_insert_or_query ;
 
+character_or_special_list:
+       character_or_special character_or_special_list
+       | character_or_special ;
+
 character_or_special_or_insert_or_query:
+       character_or_special
+       | query
+       | query_not
+       | insert ;
+
+character_or_special:
        special
        | character
        {
                INSERT_CHARACTER($1);
-       }
-       | query
-       | insert ;
+       };
 
 character:
        CHARACTER
@@ -503,7 +543,7 @@ special:
                quote_fmt_show_first_name(msginfo);
        }
        | SHOW_LAST_NAME
-        {
+    {
                quote_fmt_show_last_name(msginfo);
        }
        | SHOW_SENDER_INITIAL
@@ -536,9 +576,12 @@ special:
        }
        | SHOW_REFERENCES
        {
-                /* CLAWS: use in reply to header */
-               /* if (msginfo->references)
-                       INSERT(msginfo->references); */
+               GSList *item;
+
+               INSERT(msginfo->inreplyto);
+               for (item = msginfo->references; item != NULL; item = g_slist_next(item))
+                       if (item->data)
+                               INSERT(item->data);
        }
        | SHOW_MESSAGE
        {
@@ -572,6 +615,10 @@ special:
        {
                INSERT("?");
        }
+       | SHOW_EXCLAMATION_MARK
+       {
+               INSERT("!");
+       }
        | SHOW_PIPE
        {
                INSERT("|");
@@ -586,7 +633,7 @@ special:
        }
        | SET_CURSOR_POS
        {
-               cursor_pos = bufsize;
+               cursor_pos = current->bufsize;
        };
 
 query:
@@ -656,8 +703,95 @@ query:
        }
        | QUERY_REFERENCES
        {
-                /* CLAWS: use in-reply-to header */
-               /* add_visibility(msginfo->references != NULL); */
+               gboolean found;
+               GSList *item;
+
+               found = (msginfo->inreplyto != NULL);
+               for (item = msginfo->references; found == FALSE && item != NULL; item = g_slist_next(item))
+                       if (item->data)
+                               found = TRUE;
+               add_visibility(found == TRUE);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       };
+
+query_not:
+       QUERY_NOT_DATE
+       {
+               add_visibility(msginfo->date == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_FROM
+       {
+               add_visibility(msginfo->from == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_FULLNAME
+       {
+               add_visibility(msginfo->fromname == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_SUBJECT
+       {
+               add_visibility(msginfo->subject == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_TO
+       {
+               add_visibility(msginfo->to == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_NEWSGROUPS
+       {
+               add_visibility(msginfo->newsgroups == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_MESSAGEID
+       {
+               add_visibility(msginfo->msgid == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_CC
+       {
+               add_visibility(msginfo->cc == NULL);
+       }
+       OPARENT quote_fmt CPARENT
+       {
+               remove_visibility();
+       }
+       | QUERY_NOT_REFERENCES
+       {
+               gboolean found;
+               GSList *item;
+
+               found = (msginfo->inreplyto != NULL);
+               for (item = msginfo->references; found == FALSE && item != NULL; item = g_slist_next(item))
+                       if (item->data)
+                               found = TRUE;
+               add_visibility(found == FALSE);
        }
        OPARENT quote_fmt CPARENT
        {
@@ -665,15 +799,27 @@ query:
        };
 
 insert:
-       INSERT_FILE OPARENT string CPARENT
+       INSERT_FILE
+       {
+               current = &sub_expr;
+               clear_buffer();
+       }
+       OPARENT sub_expr CPARENT
        {
+               current = &main_expr;
                if (!dry_run) {
-                       quote_fmt_insert_file($3);
+                       quote_fmt_insert_file(sub_expr.buffer);
                }
        }
-       | INSERT_PROGRAMOUTPUT OPARENT string CPARENT
+       | INSERT_PROGRAMOUTPUT
+       {
+               current = &sub_expr;
+               clear_buffer();
+       }
+       OPARENT sub_expr CPARENT
        {
+               current = &main_expr;
                if (!dry_run) {
-                       quote_fmt_insert_program_output($3);
+                       quote_fmt_insert_program_output(sub_expr.buffer);
                }
        };