]> git.deb.at Git - pkg/abook.git/commitdiff
miscellaneous fixes & doc: i18n, custom format and vcard
authorRaphaël Droz <raphael.droz+floss@gmail.com>
Sun, 20 Jan 2013 16:20:44 +0000 (17:20 +0100)
committerRaphaël Droz <raphael.droz+floss@gmail.com>
Sun, 20 Jan 2013 17:09:53 +0000 (18:09 +0100)
* converted HOWTO.translating_abook to UTF-8, added a couple of lines
 about quickly installing and testing new translations and updated URL
 of some po-related softwares.

* fixed a trivial error with custom format strncpy() initialization

* vcard builtin import: removed variables unused since e3aa1d4

* vcard export: set a "PREF" EMAIL field attribute (not [yet]
  used by vcard import though)

* vcard libvformat import:
  - fixed segfault on 64bits arch where a va_list's NULL sentinel value
    must be properly casted [sizeof(int) != sizeof(char *)]
  - now really import multivalued fields (better use of libvformat):
    VFGP_FIND instead of VFGP_GET + vf_get_next_property()
  - use of abook_list instead of strconcat for multivalued fields
    (groups and emails)
  - no more duplicated phone numbers if one or more *PHONE/FAX is
    provided while no HOMEPHONE is available

abook.c
doc/HOWTO.translating_abook
filter.c
vcard.c

diff --git a/abook.c b/abook.c
index 05ec4293d37290d4644ddd22b74782528864d93a..1651267a541ef44bc5352786ca121777ce298fd3 100644 (file)
--- a/abook.c
+++ b/abook.c
@@ -390,8 +390,8 @@ parse_command_line(int argc, char **argv)
                                selected_item_filter = select_output_item_filter(outformat);
                                break;
                        case OPT_OUTFORMAT_STR:
-                               strncpy(custom_format, optarg, FORMAT_STRING_LEN - 1);
-                               custom_format[FORMAT_STRING_LEN] = 0;
+                               strncpy(custom_format, optarg, FORMAT_STRING_LEN);
+                               custom_format[FORMAT_STRING_LEN - 1] = 0;
                                break;
                        case OPT_INFILE:
                                set_convert_var(infile);
index 2dfec7dd669e633ab90603a5cd8b1b51944104ea..0c303a710abd4844ac4eeec10bb7cc6bf306fc65 100644 (file)
@@ -193,7 +193,7 @@ A few notes:
   contributors can contact you if they want to join you in the
   translation team, or have remarks/typo fixes to give about the
   translations. You can either just give your name/nick, or add an email
-  address, f ex "Last-Translator: Cédric Duval <cedricduval+abook@free.fr>\n".
+  address, f ex "Last-Translator: Cédric Duval <cedricduval+abook@free.fr>\n".
 
 * Comments
   Adding comments (lines begining with the '#' character) can be a good
@@ -207,6 +207,12 @@ A few notes:
   (standard length is 80 characters). Don't translate blindly, try to
   look where your string will be displayed to adapt your translation.
 
+* Testing translations
+  To give a look at the live translations without really installing abook
+  you can install abook and its mo files in a subdirectory:
+  ./configure --prefix $(pwd)/fakeinstall/usr ; make install
+  Then, eg: LANGUAGE=sv ./fakeinstall/usr/bin/abook
+
 * A few useful tools
   The po-file format is very simple, and the file can be edited with a
   standard text editor.
@@ -214,8 +220,8 @@ A few notes:
   But if you prefer, there are few specialized tools you may find
   convenient for translating:
    * poEdit (http://www.poedit.org/)
-   * KBabel (http://i18n.kde.org/tools/kbabel/)
-   * GTranslator (http://gtranslator.sourceforge.net/)
+   * Lokalize (http://userbase.kde.org/Lokalize/)
+   * GTranslator (http://projects.gnome.org/gtranslator/)
    * Emacs po mode
    * Vim po mode
      (http://vim.sourceforge.net/scripts/script.php?script_id=695
@@ -229,6 +235,6 @@ And finally
 I hope you'll have fun contributing to a more internationalized world. :)
 
 If you have any more questions, don't hesitate to contact me
-(Cédric Duval <cedricduval+abook@free.fr>) or the abook development
+(Cédric Duval <cedricduval+abook@free.fr>) or the abook development
 mailing list (http://lists.sourceforge.net/lists/listinfo/abook-devel).
 
index 613a827dd2ec0eb0847942c341c349992560a9a6..20c89739623de515398e183a4873d247d0b36f0e 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -1645,10 +1645,7 @@ vcard_parse_email(list_item item, char *line)
 static void
 vcard_parse_address(list_item item, char *line)
 {
-       int i;
-       int k;
        char *value;
-       char *address_field;
 
        value = vcard_get_line_element(line, VCARD_VALUE);
        if(!value)
@@ -2000,7 +1997,7 @@ vcard_export_database(FILE *out, struct db_enumerator e)
 void
 vcard_export_item(FILE *out, int item)
 {
-       int j;
+       int j, email_no;
        char *name, *tmp;
        abook_list *emails, *em;
        fprintf(out, "BEGIN:VCARD\r\nFN:%s\r\n",
@@ -2048,9 +2045,10 @@ vcard_export_item(FILE *out, int item)
        tmp = db_email_get(item);
        if(*tmp) {
          emails = csv_to_abook_list(tmp);
-
-         for(em = emails; em; em = em->next)
-           fprintf(out, "EMAIL;INTERNET:%s\r\n", em->data);
+         fprintf(out, "EMAIL;PREF;INTERNET:%s\r\n", emails->data);
+         email_no = 1;
+         for(em = emails->next; em; em = em->next, email_no++ )
+                 fprintf(out, "EMAIL;%d;INTERNET:%s\r\n", email_no, em->data);
 
          abook_list_free(&emails);
        }
diff --git a/vcard.c b/vcard.c
index 0ff564212eee2a3c7dd5ce44885f96957c3715e2..060de88718b595e3e266c9e6d5bc4ea6732bb136 100644 (file)
--- a/vcard.c
+++ b/vcard.c
@@ -16,6 +16,8 @@
 #include <string.h>
 
 #include "database.h"
+#include "options.h" // bool
+#include "misc.h" // abook_list_to_csv
 #include "xmalloc.h"
 
 #include "vcard.h"
@@ -32,51 +34,50 @@ int vcard_parse_file_libvformat(char *filename) {
   // property number (used for multivalued properties)
   int props = 0;
   // temporary values
-  char *propval;
-  char multival[MAX_FIELD_LEN] = { 0 };
-  size_t available = MAX_FIELD_LEN;
+  abook_list *multivalues = NULL;
+  char *propval = 0;
+  bool phone_found;
 
   do {
     list_item item = item_create();
+    phone_found = false;
+    /* Note: libvformat use va_args, we *must* cast the last
+       NULL argument to (char*) for arch where
+       sizeof(int) != sizeof(char *) */
 
     // fullname [ or struct-name [ or name ] ]
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "FN", NULL))
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "FN", (char*)0))
       if ((propval = vf_get_prop_value_string(prop, 0)))
        item_fput(item, NAME, xstrdup(propval));
 
-    if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "N", "*", NULL)) {
-      // TODO: GIVENNAME , FAMILYNAME
+    if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "N", (char*)0)) {
+      // TODO: GIVENNAME, FAMILYNAME
       propval = vf_get_prop_value_string(prop, 0);
       if(propval)
        item_fput(item, NAME, xstrdup(propval));
     }
 
-    if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NAME", NULL)) {
+    if (!propval && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NAME", (char*)0)) {
       propval = vf_get_prop_value_string(prop, 0);
       if(propval)
        item_fput(item, NAME, xstrdup(propval));
     }
 
-    // email(s)
-    // TODO: use our strconcat() ?
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "EMAIL", NULL)) {
-      props = 0;
-      available = MAX_FIELD_LEN;
-      while (available > 0 && props < 5) {
-       propval = vf_get_prop_value_string(prop, props++);
-       if(!propval) continue;
-       if (available > 0 && *multival != 0)
-         strncat(multival, ",", available--);
-       strncat(multival, propval, available);
-       available -= strlen(propval);
-      }
-      if (available < MAX_FIELD_LEN)
-       item_fput(item, EMAIL, xstrdup(multival));
+    // email(s). (TODO: EMAIL;PREF: should be abook's first)
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "EMAIL", (char*)0)) {
+           do {
+                   props = 0;
+                   while ((propval = vf_get_prop_value_string(prop, props++))) {
+                           abook_list_append(&multivalues, propval);
+                   }
+           } while (vf_get_next_property(&prop));
+           item_fput(item, EMAIL, abook_list_to_csv(multivalues));
+           abook_list_free(&multivalues);
     }
 
     // format for ADR:
     // PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", NULL)) {
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", (char*)0)) {
       props = 0;
       // PO Box: abook ignores
       vf_get_prop_value_string(prop, props++);
@@ -101,91 +102,65 @@ int vcard_parse_file_libvformat(char *filename) {
       if(propval) item_fput(item, COUNTRY, xstrdup(propval));
     }
 
-
-    /*
-    // city: not in libvformat
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "ADR", "CITY", NULL)) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, CITY, xstrdup(propval));
-    }
-    // state
-    // zip
-    // country
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "C", NULL)) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, COUNTRY, xstrdup(propval));
+    // phone numbers
+    // home
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "HOME", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
+           item_fput(item, PHONE, xstrdup(propval)); phone_found = true;
     }
-    */
-
-    // phone
-    // check for HOME
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "HOME")) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, PHONE, xstrdup(propval));
-    }
-    // or grab a more generic one otherwise
-    else if(vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", NULL)) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, PHONE, xstrdup(propval));
-    }
-
     // workphone
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "WORK", NULL)) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, WORKPHONE, xstrdup(propval));
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "WORK", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
+           item_fput(item, WORKPHONE, xstrdup(propval)); phone_found = true;
     }
 
     // fax
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "FAX", NULL)) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, FAX, xstrdup(propval));
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "FAX", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
+           item_fput(item, FAX, xstrdup(propval)); phone_found = true;
     }
 
     // cellphone
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "CELL", NULL)) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, MOBILEPHONE, xstrdup(propval));
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", "CELL", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
+           item_fput(item, MOBILEPHONE, xstrdup(propval)); phone_found = true;
+    }
+
+    // or grab any other one as default
+    if(! phone_found && vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "TEL", (char*)0) && (propval = vf_get_prop_value_string(prop, 0))) {
+           item_fput(item, PHONE, xstrdup(propval));
     }
 
     // nick
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NICKNAME", NULL)) {
-      propval = vf_get_prop_value_string(prop, 0);
-      item_fput(item, NICK, xstrdup(propval));
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NICKNAME", (char*)0)) {
+           propval = vf_get_prop_value_string(prop, 0);
+           item_fput(item, NICK, xstrdup(propval));
     }
 
     // url
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "URL", NULL)) {
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "URL", (char*)0)) {
       propval = vf_get_prop_value_string(prop, 0);
       item_fput(item, URL, xstrdup(propval));
     }
 
     // notes
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NOTE", NULL)) {
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "NOTE", (char*)0)) {
       propval = vf_get_prop_value_string(prop, 0);
       item_fput(item, NOTES, xstrdup(propval));
     }
 
     // anniversary
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "BDAY", NULL)) {
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "BDAY", (char*)0)) {
       propval = vf_get_prop_value_string(prop, 0);
       item_fput(item, ANNIVERSARY, xstrdup(propval));
     }
 
     // (mutt) groups
-    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "CATEGORIES", NULL)) {
-       props = 0;
-       available = MAX_FIELD_LEN;
-       *multival = 0;
-       while (available > 0 && props < 5) {
-         propval = vf_get_prop_value_string(prop, props++);
-         if(!propval) continue;
-         if (available > 0 && *multival != 0)
-           strncat(multival, ",", available--);
-         strncat(multival, propval, available);
-         available -= strlen(propval);
-       }
-       if (available < MAX_FIELD_LEN)
-         item_fput(item, GROUPS, xstrdup(multival));
+    if (vf_get_property(&prop, vfobj, VFGP_FIND, NULL, "CATEGORIES", (char*)0)) {
+           do {
+                   props = 0;
+                   while ((propval = vf_get_prop_value_string(prop, props++))) {
+                           abook_list_append(&multivalues, propval);
+                   }
+           } while (vf_get_next_property(&prop));
+           item_fput(item, GROUPS, abook_list_to_csv(multivalues));
+           abook_list_free(&multivalues);
     }
 
     add_item2database(item);