]> git.deb.at Git - pkg/abook.git/blobdiff - filter.c
vcard export: ADR field's components now respect the order
[pkg/abook.git] / filter.c
index c8b3d9ea6d82b02f59fb9030919dbaad70b0379c..4d1abd893f018cdacc9e6e2e8c41852eb76889a1 100644 (file)
--- a/filter.c
+++ b/filter.c
@@ -503,8 +503,6 @@ export_file(char filtname[FILTNAME_LEN], char *filename)
 
 #include "ldif.h"
 
-static void    ldif_fix_string(char *str);
-
 /* During LDIF import we need more fields than the
    ITEM_FIELDS of a *list_item. Eg: "objectclass"
    to test valid records, ...
@@ -789,8 +787,6 @@ ldif_parse_file(FILE *handle)
                        continue; /* just skip the errors */
                }
 
-               ldif_fix_string(value);
-
                ldif_convert(item, type, value);
 
                xfree(line);
@@ -802,19 +798,6 @@ ldif_parse_file(FILE *handle)
        return 0;
 }
 
-static void
-ldif_fix_string(char *str)
-{
-       int i, j;
-
-       for(i = 0, j = 0; j < (int)strlen(str); i++, j++)
-               str[i] = ( str[j] == (char)0xc3 ?
-                               (char) str[++j] + (char) 0x40 :
-                               str[j] );
-
-       str[i] = 0;
-}
-
 /*
  * end of ldif import
  */
@@ -2044,15 +2027,18 @@ vcard_export_item(FILE *out, int item)
 
        free(name);
 
-       if(db_fget(item, ADDRESS))
-         fprintf(out, "ADR:;;%s;%s;%s;%s;%s;%s\r\n",
-                 safe_str(db_fget(item, ADDRESS)),
-                 safe_str(db_fget(item, ADDRESS2)),
-                 safe_str(db_fget(item, CITY)),
-                 safe_str(db_fget(item, STATE)),
-                 safe_str(db_fget(item, ZIP)),
-                 safe_str(db_fget(item, COUNTRY))
-                 );
+       // see rfc6350 section 6.3.1
+       if(db_fget(item, ADDRESS)) {
+               fprintf(out, "ADR:;%s;%s;%s;%s;%s;%s\r\n",
+                       // pobox (unsupported)
+                       safe_str(db_fget(item, ADDRESS2)), // ext (n°, ...)
+                       safe_str(db_fget(item, ADDRESS)), // street
+                       safe_str(db_fget(item, CITY)), // locality
+                       safe_str(db_fget(item, STATE)), // region
+                       safe_str(db_fget(item, ZIP)), // code (postal)
+                       safe_str(db_fget(item, COUNTRY)) // country
+                       );
+       }
 
        if(db_fget(item, PHONE))
          fprintf(out, "TEL;HOME:%s\r\n",
@@ -2502,37 +2488,15 @@ bsdcal_export_database(FILE *out, struct db_enumerator e)
        return 0;
 }
 
-// see enum field_types @database.h
-static char *conv_table[] = {
-  "name",
-  "email",
-  "address",
-  "address2",
-  "city",
-  "state",
-  "zip",
-  "country",
-  "phone",
-  "workphone",
-  "fax",
-  "mobile",
-  "nick",
-  "url",
-  "notes",
-  "anniversary",
-  0 /* ITEM_FIELDS */
-};
-
+// see also enum field_types @database.h
+extern abook_field standard_fields[];
 static int
 find_field_enum(char *s) {
-  int i = 0;
-  while (conv_table[i]) {
-    if(!safe_strcmp(conv_table[i], s))
-      return i;
-    i++;
-  }
-  // failed
-  return -1;
+       int i = -1;
+       while(standard_fields[++i].key)
+               if(!strcmp(standard_fields[i].key, s))
+                       return i;
+       return -1;
 }
 
 /* Convert a string with named placeholders to
@@ -2546,17 +2510,17 @@ parse_custom_format(char *s, char *fmt_string, enum field_types *ft)
          exit(EXIT_FAILURE);
        }
 
+       char tmp[1] = { 0 };
        char *p, *start, *field_name = NULL;
        p = start = s;
 
        while(*p) {
                if(*p == '{') {
                  start = ++p;
+
+                 if(! *start) goto cannotparse;
                  p = strchr(start, '}');
-                 if(! *p) {
-                   fprintf(stderr, _("parse_custom_format: invalid format\n"));
-                   exit(EXIT_FAILURE);
-                 }
+                 if(! p) goto cannotparse;
                  strcat(fmt_string, "%s");
                  field_name = strndup(start, (size_t)(p-start));
                  *ft = find_field_enum(field_name);
@@ -2566,23 +2530,53 @@ parse_custom_format(char *s, char *fmt_string, enum field_types *ft)
                  }
 
                  ft++;
-                 p++;
-                 start = p;
-               } else {
+                 start = ++p;
+               }
+
+               else if(*p == '\\') {
+                       ++p;
+                       if(! *p) tmp[0] = '\\'; // last char is a '\' ?
+                       else if(*p == 'n') *tmp = '\n';
+                       else if(*p == 't') *tmp = '\t';
+                       else if(*p == 'r') *tmp = '\r';
+                       else if(*p == 'v') *tmp = '\v';
+                       else if(*p == 'b') *tmp = '\b';
+                       else if(*p == 'a') *tmp = '\a';
+                       else *tmp = *p;
+                       strncat(fmt_string, tmp, 1);
+                       start = ++p;
+               }
+
+               // if no '\' following: quick mode using strchr/strncat
+               else if(! strchr(start, '\\')) {
                  p = strchr(start, '{');
-                 if(p && *p) {
+                 if(p) { // copy until the next placeholder
                    strncat(fmt_string, start, (size_t)(p-start));
                    start = p;
                  }
-                 else {
+                 else { // copy till the end
                    strncat( fmt_string,
                             start,
                             FORMAT_STRING_LEN - strlen(fmt_string) - 1 );
                    break;
                  }
                }
+
+               // otherwise character by character
+               else {
+                       strncat(fmt_string, p, 1);
+                       start = ++p;
+               }
        }
-       *ft = 66;
+
+       *ft = ITEM_FIELDS;
+       return;
+
+ cannotparse:
+       fprintf(stderr, _("%s: invalid format, index %ld\n"), __FUNCTION__, (start - s));
+       free(fmt_string);
+       while(*ft) free(ft--);
+       exit(EXIT_FAILURE);
 }
 
 static int
@@ -2615,7 +2609,7 @@ custom_export_item(FILE *out, int item, char *fmt, enum field_types *ft)
   // we first check that all fields exist before continuing
   if(*fmt == '!') {
     enum field_types *ftp = ft;
-    while(*ft != 66) {
+    while(*ft != ITEM_FIELDS) {
       if(! db_fget(item, *ft) )
        return 1;
       ft++;
@@ -2629,7 +2623,7 @@ custom_export_item(FILE *out, int item, char *fmt, enum field_types *ft)
       fprintf(out, "%s", safe_str(db_fget(item, *ft)));
       ft++;
       fmt+=2;
-    } else if (*ft == 66) {
+    } else if (*ft == ITEM_FIELDS) {
       fprintf(out, "%s", fmt);
       return 0;
     } else {