On Mon, Sep 24, 2012 at 08:49:28AM +0200, Fabio wrote:
> On Sun, Sep 23, 2012 at 11:39:50PM +0200, Raphaël wrote:
> > But I got more mixed results on the input filter side (unrelated to the
> > use of -addr):
> 
> Note that I only parse the -group option of the mutt "alias" file, i.e.
> something like:
> 
> alias -group XX nick name surname address

I can now confirm that it works well for such patterns.

Thinking a bit more about this I found misleading that we only handle 1
address and silently drop other possible cases like: 
> alias -group XX nick name surname addr@ess1, name2 addr@ess2
or even
> alias nick <addr@ess1>, <addr@ess2>

I don't know how used the syntax is but the attached patch (applies on top of
yours) handles such cases where a -group lines has multiple associated
addresses.

But I (partly) wonder about the way to handle:
> alias -group XX nick name surname add@ress, some string surname2 name2 
> <addr@ess2>
which provides addr@ess2 as part of the "nick" alias.
( addr@ess2 must be <delimited> for mutt to work )

While defining two distinct aliases in the same line is not permitted
(nor really useful) for mutt, should we play nicer at this ? we can:
[1] store the same alias ("nick") for all items in the line
[2] not store any alias except for the first item
[3] try to extract an alias from the string preceding each email (except
    the first one where alias is explicit).

Unless I missed something, [1] is useless and confusing for users.
[2] is safe, simple and matches muttrc(5) documentation
[3] may be smart but not fool-proof as we can't say for sure that "some"
    is the NICK to give to "name2" or a part of its full-name


The second question is about what to do when we don't parse, eg:
> alias alias1 alias2
is valid for mutt but not for abook (even if searching the db were
reasonable, we couldn't store 2 aliases for 1 item).
The current behavior is email=name=alias2 + nick=alias1 which is
obviously wrong.
Should we print a warning and/or skip the item or just fail ?
[ when mutt can't parse it warns then ask whether to continue or not,
but I don't find this behavior useful for abook ]


About the current patch:
That fact that multiple items may be created forced me to bring
mutt_read_line() code inside mutt_parse_file().
I replaced some broken and disabled code from mutt_fix_quoting(), ending
with a reduced code size (hopefully more readable too)
(as a bonus it now works for non-terminated lines and should
not segfault anymore in some edge-cases)
The current version sets the nick for the 1st item only (above solution [2])

see also:
$ ./abook --convert --informat mutt --outformat abook < testcase.muttrc |\
  ./abook --convert --informat abook --outformat mutt



any thoughts appreciated


regards
diff --git a/filter.c b/filter.c
index c7f5632..8c208fa 100644
--- a/filter.c
+++ b/filter.c
@@ -1,4 +1,4 @@
-
+/* -*- c-basic-offset: 4 -*- */
 /*
  * $Id$
  *
@@ -637,60 +637,6 @@ ldif_fix_string(char *str)
 
 #include "getname.h"
 
-static int
-mutt_read_line(FILE *in, char **groups, char **alias, char **rest)
-{
-       char *line, *ptr;
-       char *start, *end;
-       abook_list *glist = NULL;
-
-       if( !(line = ptr = getaline(in)) )
-               return 1; /* error / EOF */
-
-       SKIPWS(ptr);
-
-       if(strncmp("alias", ptr, 5)) {
-               free(line);
-               return 1;
-       }
-
-       ptr += 5;
-       SKIPWS(ptr);
-
-       /* If the group option is used, save the groups */
-       *groups = NULL;
-       start = ptr;
-       int n_groups;
-       for(n_groups = 0; 0 == strncmp("-group", ptr, 6); n_groups++) {
-               ptr += 6;
-               SKIPWS(ptr);
-               start = ptr;
-               SKIPNONWS(ptr);
-               end = ptr;
-               abook_list_append(&glist,xstrndup(start, end - start));
-               SKIPWS(ptr);
-       }
-
-       if(n_groups && groups)
-               *groups = abook_list_to_csv(glist);
-
-       abook_list_free(&glist);        
-
-       /* alias */
-       start = ptr;
-       SKIPNONWS(ptr);
-       end = ptr;
-       SKIPWS(ptr);
-       if(alias)
-               *alias = xstrndup(start, end - start);
-
-       /* rest (email) */
-       *rest = xstrdup(ptr);
-
-       xfree(line);
-       return 0;
-}
-
 static void
 mutt_fix_quoting(char *p)
 {
@@ -717,10 +663,6 @@ mutt_parse_email(list_item item)
        char *line = item_fget(item, NAME);
        char *tmp;
        char *name, *email;
-#if 0
-       char *start = line;
-       int i = 0;
-#endif
 
        mutt_fix_quoting(line);
        tmp = strconcat("From: ", line, NULL);
@@ -736,50 +678,99 @@ mutt_parse_email(list_item item)
                item_fput(item, EMAIL, email);
        else
                return;
-
-       /*
-        * this is completely broken
-        */
-#if 0
-       while( (start = strchr(start, ',')) && i++ < MAX_EMAILS - 1) {
-               tmp = strconcat("From: ", ++start, NULL);
-               getname(tmp, &name, &email);
-               free(tmp);
-               free(name);
-               if(email) {
-                       if(*email) {
-                               tmp = strconcat(item[EMAIL], ",", email, NULL);
-                               free(item[EMAIL]);
-                               item[EMAIL] = tmp;
-                       } else {
-                               xfree(email);
-                       }
-               }
-       }
-#endif
 }
 
 static int
 mutt_parse_file(FILE *in)
 {
        list_item item = item_create();
+       char *line = NULL, *ptr, *groups, *alias;
+       char *start, *end;
 
-       for(;;) {
-               memset(item, 0, fields_count * sizeof(char *));
+       int n_groups, line_n = 0;
+       abook_list *glist;
+
+       while(!feof(in)) {
+           line_n++;
 
-               if(!mutt_read_line(in,
-                       (field_id(GROUPS) != -1) ? &item[field_id(GROUPS)] : 
NULL,
-                       (field_id(NICK) != -1) ? &item[field_id(NICK)] : NULL,
-                       &item[field_id(NAME)]) )
-                       mutt_parse_email(item);
+           if( !(line = ptr = getaline(in)) )
+               break; /* error / EOF */
 
-               if(feof(in)) {
-                       item_empty(item);
-                       break;
+           SKIPWS(ptr);
+
+           if(strncmp("alias", ptr, 5)) {
+               free(line);
+               continue;
+           }
+
+           ptr += 5;
+           SKIPWS(ptr);
+
+           // search for groups in the line
+           n_groups = 0; groups = NULL; glist = NULL;
+           start = ptr;
+           for(n_groups = 0; 0 == strncmp("-group", ptr, 6); n_groups++) {
+               ptr += 6;
+               SKIPWS(ptr);
+               start = ptr;
+               SKIPNONWS(ptr);
+               end = ptr;
+               abook_list_append(&glist,xstrndup(start, end - start));
+               SKIPWS(ptr);
+           }
+           // costless if no groups
+           groups = abook_list_to_csv(glist);
+           abook_list_free(&glist);
+
+           // the position of the alias (chunk will be copied into NICK)
+           start = ptr;
+           SKIPNONWS(ptr);
+           if(ptr-start == 0) {
+               fprintf(stderr, "no alias found, line %d\n", line_n);
+               goto muttbailout;
+           }
+
+           alias = xstrndup(start, ptr - start);
+           // will start with the first token
+           // then *end will be NULLed
+           end = ptr;
+
+           // comma-separated "[full name] <em@il>" token(s)
+           // following the above (unique) alias
+           while ((ptr = strtok(ptr, ",")) != NULL) {
+               SKIPWS(ptr);
+               // warn and skip (or should we fail ?) on invalid syntax
+               // (Mutt supports "alias second-alias previous-alias" but we 
don't)
+               if(!*ptr || strchr(ptr, '@') == NULL) {
+                   fprintf(stderr, "parse error, line %d\n", line_n);
+                   ptr = 0;
+                   continue;
+               }
+
+               memset(item, 0, fields_count * sizeof(char *));
+               if(groups)
+                   item_fput(item, GROUPS, xstrdup(groups));
+               // the alias only applies to the first item, reset end
+               // after the first item
+               if(end) {
+                   item_fput(item, NICK, xstrdup(alias));
+                   end = 0;
                }
 
+               // mutt_parse_email() will take care of splitting this correctly
+               item_fput(item, NAME, ptr);
+               mutt_parse_email(item);
                add_item2database(item);
+               ptr = 0;
+           }
+
+           free(alias);
+
+       muttbailout:
+           free(groups);
+           free(line);
        }
+
        item_free(&item);
 
        return 0;
alias -group GRP1 -group GRP2 alias1 Given1 Surname1 <peop...@line1.com>, 
Second Guy <second...@line1.com>
alias -group GRP3 -group GRP4 alias3 ema...@line2.com, Foo n...@brack.et
alias family mot...@family.com, d...@family.com, my little brother 
<brot...@family.com>
alias noname <non...@line4.net>, <nona...@line4.net>, <nona...@line4.net>
alias noname2 nona...@nobrack.et
# wrong syntax
alias
alias A
alias -group A
alias -group A A
alias -group A @
alias -group A @A
alias -group A A @
alias -group A C C,,
# should be taken into account
alias noname3 nona...@no.eol
------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________
Abook-devel mailing list
Abook-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/abook-devel

Reply via email to