Il giorno ven, 24/02/2006 alle 16.26 +0100, Nabil Sayegh ha scritto:
> Am Freitag, 24. Februar 2006 15:00 schrieb Sergio CERLESi:
> > If you are interesting I wrote a sequence of patch that I and others
> > people on my office used:

> Great, could you please attach them?

> rgds

Hi Nabil,

I'm very happy to known that you are interesting!

Don't hesitate to call me for anything.

Now, I'm going offline, have a nice week.

Regards
Sergio
--- ./lib/contact.c.Orig	2006-01-17 18:50:13.000000000 +0100
+++ ./lib/contact.c	2006-01-18 09:33:21.000000000 +0100
@@ -718,15 +718,71 @@
 	bool utf8;	/* default charset is utf8 */
 } Parser;
 
+typedef enum _field_index
+{
+/*
+  INDEX_NOTE,
+*/
+  INDEX_SUFFIX,
+  INDEX_FIRST_NAME,
+  INDEX_WORK_TEL,
+  INDEX_HOME_TEL,
+  INDEX_LAST_NAME,
+  INDEX_COMPANY,
+  INDEX_JOB_TITLE,
+  INDEX_DEPARTMENT,
+  INDEX_OFFICE_LOC,
+  INDEX_MOBILE_TEL,
+  INDEX_RADIO_TEL,
+  INDEX_CAR_TEL,
+  INDEX_WORK_FAX,
+  INDEX_HOME_FAX,
+  INDEX_HOME2_TEL,
+  INDEX_BIRTHDAY,
+  INDEX_ANNIVERSARY,
+  INDEX_CATEGORY,
+  INDEX_ASSISTANT,
+  INDEX_ASSISTANT_TEL,
+/*
+  INDEX_CHILDREN,
+*/
+  INDEX_WORK2_TEL,
+  INDEX_WEB_PAGE,
+  INDEX_PAGER,
+  INDEX_SPOUSE,
+  INDEX_FULL_NAME,
+  INDEX_TITLE,
+  INDEX_MIDDLE_NAME,
+  INDEX_HOME_STREET,
+  INDEX_HOME_LOCALITY,
+  INDEX_HOME_REGION,
+  INDEX_HOME_POSTAL_CODE,
+  INDEX_HOME_COUNTRY,
+  INDEX_WORK_STREET,
+  INDEX_WORK_LOCALITY,
+  INDEX_WORK_REGION,
+  INDEX_WORK_POSTAL_CODE,
+  INDEX_WORK_COUNTRY,
+  INDEX_OTHER_STREET,
+  INDEX_OTHER_LOCALITY,
+  INDEX_OTHER_REGION,
+  INDEX_OTHER_POSTAL_CODE,
+  INDEX_OTHER_COUNTRY,
+  INDEX_EMAIL,
+  INDEX_EMAIL2,
+  INDEX_EMAIL3,
+  ID_COUNT
+} field_index;
+
 #define NAME_FIELD_COUNT 5
 
-static uint32_t name_ids[NAME_FIELD_COUNT] =
+static uint32_t name_index[NAME_FIELD_COUNT] =
 {
-	ID_LAST_NAME,
-	ID_FIRST_NAME,
-	ID_MIDDLE_NAME,
-	ID_TITLE,
-	ID_SUFFIX
+  INDEX_LAST_NAME,
+  INDEX_FIRST_NAME,
+  INDEX_MIDDLE_NAME,
+  INDEX_TITLE,
+  INDEX_SUFFIX
 };
 
 #define HOME 0
@@ -735,15 +791,70 @@
 
 #define ADDRESS_FIELD_COUNT 7
 
-static uint32_t address_ids[ADDRESS_FIELD_COUNT][3] = 
+static uint32_t address_index[ADDRESS_FIELD_COUNT][3] = 
 {
-	{0, 0}, /* post office box */
-	{0, 0}, /* extended address */
-	{ID_HOME_STREET,      ID_WORK_STREET,        ID_OTHER_STREET},      /* street */
-	{ID_HOME_LOCALITY,    ID_WORK_LOCALITY,      ID_OTHER_LOCALITY},    /* locality */
-	{ID_HOME_REGION,      ID_WORK_REGION,        ID_OTHER_REGION},      /* region */
-	{ID_HOME_POSTAL_CODE, ID_WORK_POSTAL_CODE,   ID_OTHER_POSTAL_CODE}, /* postal code */
-	{ID_HOME_COUNTRY,     ID_WORK_COUNTRY,       ID_OTHER_COUNTRY}      /* country */
+  {0, 0}, /* post office box */
+  {0, 0}, /* extended address */
+  {INDEX_HOME_STREET,       INDEX_WORK_STREET,       INDEX_OTHER_STREET},      /* street */
+  {INDEX_HOME_LOCALITY,     INDEX_WORK_LOCALITY,     INDEX_OTHER_LOCALITY},    /* locality */
+  {INDEX_HOME_REGION,       INDEX_WORK_REGION,       INDEX_OTHER_REGION},      /* region */
+  {INDEX_HOME_POSTAL_CODE,  INDEX_WORK_POSTAL_CODE,  INDEX_OTHER_POSTAL_CODE}, /* postal code */
+  {INDEX_HOME_COUNTRY,      INDEX_WORK_COUNTRY,      INDEX_OTHER_COUNTRY}      /* country */
+};
+
+static const uint32_t field_id[ID_COUNT] =
+{
+/*
+  ID_NOTE,
+*/
+  ID_SUFFIX,
+  ID_FIRST_NAME,
+  ID_WORK_TEL,
+  ID_HOME_TEL,
+  ID_LAST_NAME,
+  ID_COMPANY,
+  ID_JOB_TITLE,
+  ID_DEPARTMENT,
+  ID_OFFICE_LOC,
+  ID_MOBILE_TEL,
+  ID_RADIO_TEL,
+  ID_CAR_TEL,
+  ID_WORK_FAX,
+  ID_HOME_FAX,
+  ID_HOME2_TEL,
+  ID_BIRTHDAY,
+  ID_ANNIVERSARY,
+  ID_CATEGORY,
+  ID_ASSISTANT,
+  ID_ASSISTANT_TEL,
+/*
+  ID_CHILDREN,
+*/
+  ID_WORK2_TEL,
+  ID_WEB_PAGE,
+  ID_PAGER,
+  ID_SPOUSE,
+  ID_FULL_NAME,
+  ID_TITLE,
+  ID_MIDDLE_NAME,
+  ID_HOME_STREET,
+  ID_HOME_LOCALITY,
+  ID_HOME_REGION,
+  ID_HOME_POSTAL_CODE,
+  ID_HOME_COUNTRY,
+  ID_WORK_STREET,
+  ID_WORK_LOCALITY,
+  ID_WORK_REGION,
+  ID_WORK_POSTAL_CODE,
+  ID_WORK_COUNTRY,
+  ID_OTHER_STREET,
+  ID_OTHER_LOCALITY,
+  ID_OTHER_REGION,
+  ID_OTHER_POSTAL_CODE,
+  ID_OTHER_COUNTRY,
+  ID_EMAIL,
+  ID_EMAIL2,
+  ID_EMAIL3
 };
 
 static char* strdup_quoted_printable(const unsigned char* source)/*{{{*/
@@ -833,7 +944,7 @@
   return true;
 }/*}}}*/
 
-static void add_date(Parser* parser, uint32_t id, const char* type, char* value)
+static void add_date(Parser* parser, uint32_t index, const char* type, char* value)
 {
   TIME_FIELDS time_fields;
 
@@ -841,39 +952,39 @@
 
   if (date_to_struct(value, &time_fields))
   {
-    CEPROPVAL* propval = &parser->fields[parser->field_index++];
-    propval->propid = (id << 16) | CEVT_FILETIME;
+    CEPROPVAL* propval = &parser->fields[index];
+    propval->propid = (field_id[index] << 16) | CEVT_FILETIME;
     time_fields_to_filetime(&time_fields, &propval->val.filetime);
   }
 }
 
-static void add_string(Parser* parser, uint32_t id, const char* type, char* value)/*{{{*/
+static void add_string(Parser* parser, uint32_t index, const char* type, char* value)/*{{{*/
 {
-	char* converted = NULL;
-	CEPROPVAL* field = &parser->fields[parser->field_index++];
+  char* converted = NULL;
+  CEPROPVAL* field = &parser->fields[index];
 
-	assert(value);
+  assert(value);
 	
-	field->propid = (id << 16) | CEVT_LPWSTR;
+  field->propid = (field_id[index] << 16) | CEVT_LPWSTR;
 
-	if (STR_IN_STR(type, "QUOTED-PRINTABLE"))
-	{
-		value = converted = strdup_quoted_printable(value);
-		assert(value);
-	}
+  if (STR_IN_STR(type, "QUOTED-PRINTABLE"))
+  {
+    value = converted = strdup_quoted_printable(value);
+    assert(value);
+  }
 
-	unescape_string(value);
-	assert(value);
+  unescape_string(value);
+  assert(value);
 
-	if (parser->utf8 || STR_IN_STR(type, "UTF-8"))
-		field->val.lpwstr = wstr_from_utf8(value);
-	else
-		field->val.lpwstr = wstr_from_ascii(value);
+  if (parser->utf8 || STR_IN_STR(type, "UTF-8"))
+    field->val.lpwstr = wstr_from_utf8(value);
+  else
+    field->val.lpwstr = wstr_from_ascii(value);
 
-	assert(field->val.lpwstr);
+  assert(field->val.lpwstr);
 
-	if (converted)
-		free(converted);
+  if (converted)
+    free(converted);
 }/*}}}*/
 
 static bool parser_handle_field(/*{{{*/
@@ -941,7 +1052,7 @@
 	}/*}}}*/
 	else if (STR_EQUAL(name, "FN"))/*{{{*/
 	{
-		add_string(parser, ID_FULL_NAME, type, value);
+    add_string(parser, INDEX_FULL_NAME, type, value);
 	}/*}}}*/
 	else if (STR_EQUAL(name, "N"))/*{{{*/
 	{
@@ -952,7 +1063,7 @@
 		{
 			if (*name[i])
 			{
-				add_string(parser, name_ids[i], type, name[i]);
+        add_string(parser, name_index[i], type, name[i]);
 			}
 		}
 
@@ -980,9 +1091,9 @@
 		
 		for (i = 0; i < ADDRESS_FIELD_COUNT && address[i]; i++)
 		{
-			if (address_ids[i][where] && *address[i])
+      if (address_index[i][where] && *address[i])
 			{
-				add_string(parser, address_ids[i][where], type, address[i]);
+        add_string(parser, address_index[i][where], type, address[i]);
 			}
 		}
 		
@@ -996,36 +1107,36 @@
 		if (STR_IN_STR(type, "HOME"))
 		{
 			if (nth==1)
-			add_string(parser, fax ? ID_HOME_FAX : ID_HOME_TEL, type, value);
+        add_string(parser, fax ? INDEX_HOME_FAX : INDEX_HOME_TEL, type, value);
 			else
-				add_string(parser, ID_HOME2_TEL, type, value);
+        add_string(parser, INDEX_HOME2_TEL, type, value);
 		}
 		else if (STR_IN_STR(type, "WORK"))
 		{
 			if (nth==1)
-			add_string(parser, fax ? ID_WORK_FAX : ID_WORK_TEL, type, value);
+        add_string(parser, fax ? INDEX_WORK_FAX : INDEX_WORK_TEL, type, value);
 			else
-				add_string(parser, ID_WORK2_TEL, type, value);
+        add_string(parser, INDEX_WORK2_TEL, type, value);
 		}
 		else if (STR_IN_STR(type, "CELL"))
 		{
-			add_string(parser, ID_MOBILE_TEL, type, value);
+      add_string(parser, INDEX_MOBILE_TEL, type, value);
 		}
 		else if (STR_IN_STR(type, "X-EVOLUTION-ASSISTANT"))
 		{
-			add_string(parser, ID_ASSISTANT_TEL, type, value);
+      add_string(parser, INDEX_ASSISTANT_TEL, type, value);
 		}
 		else if (STR_IN_STR(type, "X-EVOLUTION-RADIO"))
 		{
-			add_string(parser, ID_RADIO_TEL, type, value);
+      add_string(parser, INDEX_RADIO_TEL, type, value);
 		}
 		else if (STR_IN_STR(type, "CAR"))
 		{
-			add_string(parser, ID_CAR_TEL, type, value);
+      add_string(parser, INDEX_CAR_TEL, type, value);
 		}
 		else if (STR_IN_STR(type, "PAGER"))
 		{
-			add_string(parser, ID_PAGER, type, value);
+      add_string(parser, INDEX_PAGER, type, value);
 		}
 		else
 		{
@@ -1046,19 +1157,19 @@
 		switch (nth)
 		{
 			case 1:
-		add_string(parser, ID_EMAIL, type, value);
+        add_string(parser, INDEX_EMAIL, type, value);
 				break;
 			case 2:
-				add_string(parser, ID_EMAIL2, type, value);
+        add_string(parser, INDEX_EMAIL2, type, value);
 				break;
 			case 3:
-				add_string(parser, ID_EMAIL3, type, value);
+        add_string(parser, INDEX_EMAIL3, type, value);
 				break;
 		}
 	}/*}}}*/
 	else if (STR_EQUAL(name, "URL"))/*{{{*/
 	{
-		add_string(parser, ID_WEB_PAGE, type, value);
+    add_string(parser, INDEX_WEB_PAGE, type, value);
 	}/*}}}*/
 	else if (STR_EQUAL(name, "ORG"))/*{{{*/
 	{
@@ -1066,19 +1177,19 @@
 		if (separator)
 		{
 			if (separator[1]) {
-				add_string(parser, ID_DEPARTMENT, type, separator + 1);
+        add_string(parser, INDEX_DEPARTMENT, type, separator + 1);
 			}
 			*separator = '\0';
 		}
 
 		if (value[0])
 		{
-			add_string(parser, ID_COMPANY, type, value);
+      add_string(parser, INDEX_COMPANY, type, value);
 		}
 	}/*}}}*/
 	else if (STR_EQUAL(name, "TITLE"))/*{{{*/
 	{
-		add_string(parser, ID_JOB_TITLE, type, value);
+    add_string(parser, INDEX_JOB_TITLE, type, value);
 	}/*}}}*/
 	else if (STR_EQUAL(name, "X-EVOLUTION-FILE-AS"))/*{{{*/
 	{
@@ -1096,27 +1207,27 @@
 	}/*}}}*/
   else if (STR_EQUAL(name, "CATEGORIES"))
   {
-    add_string(parser, ID_CATEGORY, type, value);
+    add_string(parser, INDEX_CATEGORY, type, value);
   }
   else if (STR_EQUAL(name, "BDAY"))
   {
-    add_date(parser, ID_BIRTHDAY, type, value);
+    add_date(parser, INDEX_BIRTHDAY, type, value);
   }
   else if (STR_EQUAL(name, "X-EVOLUTION-ANNIVERSARY"))
   {
-    add_date(parser, ID_ANNIVERSARY, type, value);
+    add_date(parser, INDEX_ANNIVERSARY, type, value);
   }
   else if (STR_EQUAL(name, "X-EVOLUTION-SPOUSE"))
   {
-    add_string(parser, ID_SPOUSE, type, value);
+    add_string(parser, INDEX_SPOUSE, type, value);
   }
   else if (STR_EQUAL(name, "X-EVOLUTION-ASSISTANT"))
   {
-    add_string(parser, ID_ASSISTANT, type, value);
+    add_string(parser, INDEX_ASSISTANT, type, value);
   }
   else if (STR_EQUAL(name, "X-EVOLUTION-OFFICE"))
   {
-    add_string(parser, ID_OFFICE_LOC, type, value);
+    add_string(parser, INDEX_OFFICE_LOC, type, value);
   }
 
 #if 0
@@ -1250,6 +1361,7 @@
 	size_t max_field_count = *field_count;
 	const char* p = vcard;
 	int state = VCARD_STATE_NEWLINE;
+  int count;
 	const char* name = NULL;
 	const char* name_end = NULL;
 	const char* type = NULL;
@@ -1271,6 +1383,24 @@
 	parser.field_index    = 0;
 	parser.utf8           = flags & RRA_CONTACT_UTF8;
 
+  for (count=0; count < ID_COUNT; count++)
+  {
+    CEPROPVAL* field = &parser.fields[parser.field_index++];
+
+    switch(count)
+    {
+    case INDEX_BIRTHDAY:
+    case INDEX_ANNIVERSARY:
+      field->propid = (field_id[count] << 16) |
+          CEVT_FLAG_EMPTY | CEVT_FILETIME;
+      break;
+    default:
+      field->propid = (field_id[count] << 16) |
+          CEVT_FLAG_EMPTY | CEVT_LPWSTR;
+      break;
+    }
+  }
+
 	while (*p && parser.field_index < max_field_count)
 	{
 		switch (state)
--- ./lib/contact.c.Orig	2006-01-18 09:36:16.000000000 +0100
+++ ./lib/contact.c	2006-01-18 09:36:45.000000000 +0100
@@ -953,8 +953,11 @@
   if (date_to_struct(value, &time_fields))
   {
     CEPROPVAL* propval = &parser->fields[index];
-    propval->propid = (field_id[index] << 16) | CEVT_FILETIME;
-    time_fields_to_filetime(&time_fields, &propval->val.filetime);
+    if (propval->propid & CEVT_FLAG_EMPTY)
+    {
+      propval->propid = (field_id[index] << 16) | CEVT_FILETIME;
+      time_fields_to_filetime(&time_fields, &propval->val.filetime);
+    }
   }
 }
 
@@ -965,26 +968,29 @@
 
   assert(value);
 	
-  field->propid = (field_id[index] << 16) | CEVT_LPWSTR;
-
-  if (STR_IN_STR(type, "QUOTED-PRINTABLE"))
+  if (field->propid & CEVT_FLAG_EMPTY)
   {
-    value = converted = strdup_quoted_printable(value);
+    field->propid = (field_id[index] << 16) | CEVT_LPWSTR;
+
+    if (STR_IN_STR(type, "QUOTED-PRINTABLE"))
+    {
+      value = converted = strdup_quoted_printable(value);
+      assert(value);
+    }
+  
+    unescape_string(value);
     assert(value);
+  
+    if (parser->utf8 || STR_IN_STR(type, "UTF-8"))
+      field->val.lpwstr = wstr_from_utf8(value);
+    else
+      field->val.lpwstr = wstr_from_ascii(value);
+  
+    assert(field->val.lpwstr);
+  
+    if (converted)
+      free(converted);
   }
-
-  unescape_string(value);
-  assert(value);
-
-  if (parser->utf8 || STR_IN_STR(type, "UTF-8"))
-    field->val.lpwstr = wstr_from_utf8(value);
-  else
-    field->val.lpwstr = wstr_from_ascii(value);
-
-  assert(field->val.lpwstr);
-
-  if (converted)
-    free(converted);
 }/*}}}*/
 
 static bool parser_handle_field(/*{{{*/
--- ./lib/contact.c.Orig	2006-01-18 09:40:31.000000000 +0100
+++ ./lib/contact.c	2006-01-18 09:40:38.000000000 +0100
@@ -716,6 +716,9 @@
 	CEPROPVAL* fields;
 	size_t field_index;
 	bool utf8;	/* default charset is utf8 */
+  int count_email;
+  int count_tel_work;
+  int count_tel_home;
 } Parser;
 
 typedef enum _field_index
@@ -997,8 +1000,7 @@
 		Parser* parser,
 		char* name, 
 		char* type, 
-		char* value,
-		int nth)
+    char* value)
 {
 
 	bool success = false;
@@ -1029,7 +1031,7 @@
 		}
 	}/*}}}*/
 
-	if (parser->level != 1 && nth==0)
+  if (parser->level != 1)
 	{
 		synce_error("Not within BEGIN:VCARD / END:VCARD");
 		goto exit;
@@ -1112,17 +1114,35 @@
 		/* TODO: make type uppercase */
 		if (STR_IN_STR(type, "HOME"))
 		{
-			if (nth==1)
-        add_string(parser, fax ? INDEX_HOME_FAX : INDEX_HOME_TEL, type, value);
-			else
-        add_string(parser, INDEX_HOME2_TEL, type, value);
+      if (fax) {
+        add_string(parser, INDEX_HOME_FAX, type, value);
+      } else {
+        switch (parser->count_tel_home++)
+        {
+        case 0:
+          add_string(parser, INDEX_HOME_TEL, type, value);
+          break;
+        case 1:
+          add_string(parser, INDEX_HOME2_TEL, type, value);
+          break;
+        }
+      }
 		}
 		else if (STR_IN_STR(type, "WORK"))
 		{
-			if (nth==1)
-        add_string(parser, fax ? INDEX_WORK_FAX : INDEX_WORK_TEL, type, value);
-			else
-        add_string(parser, INDEX_WORK2_TEL, type, value);
+      if (fax) {
+        add_string(parser, INDEX_WORK_FAX, type, value);
+      } else {
+        switch (parser->count_tel_work++)
+        {
+        case 0:
+          add_string(parser, INDEX_WORK_TEL, type, value);
+          break;
+        case 1:
+          add_string(parser, INDEX_WORK2_TEL, type, value);
+          break;
+        }
+      }
 		}
 		else if (STR_IN_STR(type, "CELL"))
 		{
@@ -1159,19 +1179,19 @@
 			synce_trace("Unexpected type '%s' for field '%s', assuming 'INTERNET'",
 					type, name);
 		}
-	
-		switch (nth)
-		{
-			case 1:
-        add_string(parser, INDEX_EMAIL, type, value);
-				break;
-			case 2:
-        add_string(parser, INDEX_EMAIL2, type, value);
-				break;
-			case 3:
-        add_string(parser, INDEX_EMAIL3, type, value);
-				break;
-		}
+
+    switch (parser->count_email++)
+    {
+    case 0:
+      add_string(parser, INDEX_EMAIL, type, value);
+      break;
+    case 1:
+      add_string(parser, INDEX_EMAIL2, type, value);
+      break;
+    case 2:
+      add_string(parser, INDEX_EMAIL3, type, value);
+      break;
+    }
 	}/*}}}*/
 	else if (STR_EQUAL(name, "URL"))/*{{{*/
 	{
@@ -1270,27 +1290,33 @@
 }/*}}}*/
 
 /*
+ * we add 40 for additional fields
+ * that are been handled by others application,
+ * evolution have about 28 additional fields
+ */
+#define MAX_ENQUEUE_FIELD (MAX_FIELD_COUNT + 40)
+
+/*
  * all tel_work, tel_home and email must be considered before
  * deciding which will get a slot, as there may be too many
  */
 void enqueue_field(/*{{{*/
 		struct FieldStrings *fs,
 		int *count,
-		int max,
 		struct FieldStrings *data)
 {
 	int slot=-1;
 	int i;
 
 	/* if there are free slots, there is no problem */
-	if ((*count)<max)
+  if ((*count)<MAX_ENQUEUE_FIELD)
 		slot=(*count);
 	else if (data->pref) 
 		/* so there is no free slot, but a(nother) preferred one is coming
 		   kick out a non-preferred one, if possible
 		*/
-		for (i=0; i<max; i++)
-			if (!fs[i].pref) {
+    for (i=0; i<MAX_ENQUEUE_FIELD; i++)
+      if (!fs[i].pref && !strcmp(fs[i].type, data->type)) {
 				slot=i;
 				break;
 			}
@@ -1312,21 +1338,18 @@
 	int count)
 {
 	int i;
-	int j=1;
 	char *loc;
 	
 	/* Get the first preferred and make it the preferred one on the device */
 	for (i=0; i<count; i++) {
-		if (fs[i].pref || count==(i+1)) {
+    if (fs[i].pref || i == 0) {
 			parser_handle_field(
 				parser,
 				fs[i].name,
 				fs[i].type,
-				fs[i].value,
-				1);
+        fs[i].value);
 			/* mark this as already processed */
 			fs[i].name=NULL;
-			break;
 		}
 	}
 	
@@ -1345,9 +1368,7 @@
 				parser,
 				fs[i].name,
 				fs[i].type,
-				fs[i].value,
-				j+1);
-			j++;
+        fs[i].value);
 		}
 	}
 }/*}}}*/
@@ -1375,13 +1396,10 @@
 	const char* value = NULL;
 	const char* value_end = NULL;
 
-	struct FieldStrings *tel_work  = malloc( MAX_TEL_WORK * sizeof( struct FieldStrings ) ); 
-	struct FieldStrings *tel_home  = malloc( MAX_TEL_HOME * sizeof( struct FieldStrings ) ); 
-	struct FieldStrings *email     = malloc( MAX_EMAIL * sizeof( struct FieldStrings ) ); 
+  struct FieldStrings *queue_field  = malloc( MAX_ENQUEUE_FIELD * sizeof( struct FieldStrings ) ); 
 	struct FieldStrings *tmp_field = malloc( 1 * sizeof( struct FieldStrings ) ); 
-	int count_tel_work = 0;
-	int count_tel_home = 0;
-	int count_email    = 0;
+
+  int count_field = 0;
 
 	parser.vcard_version  = RRA_CONTACT_VERSION_UNKNOWN;
 	parser.level          = 0;
@@ -1389,6 +1407,10 @@
 	parser.field_index    = 0;
 	parser.utf8           = flags & RRA_CONTACT_UTF8;
 
+  parser.count_email = 0;
+  parser.count_tel_work = 0;
+  parser.count_tel_home = 0;
+
   for (count=0; count < ID_COUNT; count++)
   {
     CEPROPVAL* field = &parser.fields[parser.field_index++];
@@ -1466,33 +1488,13 @@
 				{
 					value_end = p;
 
-					/* We have to queue tel and email fields, as there may be more than one,
-					   and we have to find out, which one is the preferred.
-					   Unfortunately there may be none, or many preferred fields :(
-					*/
-
 					tmp_field->name  = strndup(name, name_end - name);
 					tmp_field->type  = type ? strndup(type, type_end - type) : strdup("");
 					tmp_field->value = strndup(value, value_end - value);
 					tmp_field->pref  = STR_IN_STR(tmp_field->type, "PREF");
 
-					if (STR_IN_STR(tmp_field->name, "TEL") && STR_IN_STR(tmp_field->type, "WORK")) {
-						enqueue_field(tel_work, &count_tel_work, MAX_TEL_WORK, tmp_field);
-					}
-					else if (STR_IN_STR(tmp_field->name, "TEL") && STR_IN_STR(tmp_field->type, "HOME")) {
-						enqueue_field(tel_home, &count_tel_home, MAX_TEL_HOME, tmp_field);
-					}
-					else if (STR_IN_STR(tmp_field->name, "EMAIL")) {
-						enqueue_field(email, &count_email, MAX_EMAIL, tmp_field);
-					}
-					else {
-					parser_handle_field(
-							&parser,
-								tmp_field->name,
-								tmp_field->type,
-								tmp_field->value,
-								0);
-					}
+          enqueue_field(queue_field, &count_field, tmp_field);
+
 					state = VCARD_STATE_NEWLINE;
 				}
 				p++;
@@ -1504,9 +1506,7 @@
 		}
 	}
 
-	process_queue(&parser, tel_work, count_tel_work);
-	process_queue(&parser, tel_home, count_tel_home);
-	process_queue(&parser, email, count_email);
+  process_queue(&parser, queue_field, count_field);
 
 	*field_count = parser.field_index;
 
--- ./lib/contact.c.Orig	2006-01-18 09:41:46.000000000 +0100
+++ ./lib/contact.c	2006-01-18 09:44:44.000000000 +0100
@@ -700,6 +700,7 @@
 	VCARD_STATE_NAME,
 	VCARD_STATE_TYPE,
 	VCARD_STATE_VALUE,
+  VCARD_STATE_MULTILINE,
 } VcardState;
 
 #define myisblank(c)    ((c) == ' '  || (c) == '\t')
@@ -1395,6 +1396,7 @@
 	const char* type_end = NULL;
 	const char* value = NULL;
 	const char* value_end = NULL;
+  char*       value_ml = NULL;
 
   struct FieldStrings *queue_field  = malloc( MAX_ENQUEUE_FIELD * sizeof( struct FieldStrings ) ); 
 	struct FieldStrings *tmp_field = malloc( 1 * sizeof( struct FieldStrings ) ); 
@@ -1436,7 +1438,7 @@
 			case VCARD_STATE_NEWLINE:/*{{{*/
 				if (myisblank(*p))
 				{
-					synce_error("Can't handle multiline values");
+          synce_error("Failed to handle multiline values");
 					goto exit;
 				}
 
@@ -1452,6 +1454,7 @@
 					type_end  = NULL;
 					value     = NULL;
 					value_end = NULL;
+          value_ml  = NULL;
 
 					state = VCARD_STATE_NAME;
 				}
@@ -1488,6 +1491,21 @@
 				{
 					value_end = p;
 
+          if (*(p+2) && myisblank(*(p+2)))
+          {
+            value_ml = malloc(strlen(vcard) - (value - vcard));
+            value_ml[0] = '\0';
+        
+            strncat(value_ml, value, value_end - value);
+        
+            p = p + 3;
+            value = p;
+        
+            state = VCARD_STATE_MULTILINE;
+        
+            break;
+          }
+
 					tmp_field->name  = strndup(name, name_end - name);
 					tmp_field->type  = type ? strndup(type, type_end - type) : strdup("");
 					tmp_field->value = strndup(value, value_end - value);
@@ -1496,10 +1514,35 @@
           enqueue_field(queue_field, &count_field, tmp_field);
 
 					state = VCARD_STATE_NEWLINE;
+
+          if (value_ml)
+            free(value_ml);
 				}
 				p++;
 				break;/*}}}*/
 
+      case VCARD_STATE_MULTILINE:/*{{{*/
+        if (myisnewline(*p))
+        {
+          value_end = p;
+            
+          strncat(value_ml, value, value_end - value);
+            
+          if (*(p+2) && myisblank(*(p+2)))
+          {
+            p = p + 3;
+            value = p;
+          }
+          else
+          {
+            value = value_ml;
+            state = VCARD_STATE_VALUE;
+          }
+        }
+        else
+          p++;
+        break;/*}}}*/
+
 			default:
 				synce_error("Unknown state: %i", state);
 				goto exit;
--- ./lib/contact.c.Orig	2006-01-18 09:46:49.000000000 +0100
+++ ./lib/contact.c	2006-01-18 09:47:16.000000000 +0100
@@ -333,8 +333,8 @@
 				company = pFields[i].val.lpwstr;
 				break;
 
-			case ID_JOB_TITLE:
-				strbuf_append(vcard, "TITLE:");
+      case ID_JOB_ROLE:
+        strbuf_append(vcard, "ROLE:");
 				strbuf_append_escaped_wstr(vcard, pFields[i].val.lpwstr, flags);
 				strbuf_append_crlf(vcard);
 				break;
@@ -733,7 +733,7 @@
   INDEX_HOME_TEL,
   INDEX_LAST_NAME,
   INDEX_COMPANY,
-  INDEX_JOB_TITLE,
+  INDEX_JOB_ROLE,
   INDEX_DEPARTMENT,
   INDEX_OFFICE_LOC,
   INDEX_MOBILE_TEL,
@@ -817,7 +817,7 @@
   ID_HOME_TEL,
   ID_LAST_NAME,
   ID_COMPANY,
-  ID_JOB_TITLE,
+  ID_JOB_ROLE,
   ID_DEPARTMENT,
   ID_OFFICE_LOC,
   ID_MOBILE_TEL,
@@ -1214,9 +1214,9 @@
       add_string(parser, INDEX_COMPANY, type, value);
 		}
 	}/*}}}*/
-	else if (STR_EQUAL(name, "TITLE"))/*{{{*/
+  else if (STR_EQUAL(name, "ROLE"))/*{{{*/
 	{
-    add_string(parser, INDEX_JOB_TITLE, type, value);
+    add_string(parser, INDEX_JOB_ROLE, type, value);
 	}/*}}}*/
 	else if (STR_EQUAL(name, "X-EVOLUTION-FILE-AS"))/*{{{*/
 	{
--- ./lib/contact_ids.h.Orig	2006-01-18 09:46:50.000000000 +0100
+++ ./lib/contact_ids.h	2006-01-18 09:47:16.000000000 +0100
@@ -9,7 +9,7 @@
 #define ID_HOME_TEL     0x3a09
 #define ID_LAST_NAME    0x3a11
 #define ID_COMPANY      0x3a16
-#define ID_JOB_TITLE    0x3a17
+#define ID_JOB_ROLE     0x3a17
 #define ID_DEPARTMENT   0x3a18
 #define ID_OFFICE_LOC   0x3a19
 #define ID_MOBILE_TEL   0x3a1c
--- ./lib/contact.c.Orig	2006-01-18 09:49:44.000000000 +0100
+++ ./lib/contact.c	2006-01-18 09:50:00.000000000 +0100
@@ -221,6 +221,7 @@
 	/* organization parts */
 	WCHAR* company = NULL;
 	WCHAR* department = NULL;
+  WCHAR* office = NULL;
 
 	/* home address parts */
 	WCHAR* home_street = NULL;
@@ -504,9 +505,7 @@
 				break;
 
 			case ID_OFFICE_LOC:
-				strbuf_append(vcard, "X-EVOLUTION-OFFICE:");
-				strbuf_append_escaped_wstr(vcard, pFields[i].val.lpwstr, flags);
-				strbuf_append_crlf(vcard);
+        office = pFields[i].val.lpwstr;
 				break;
 
 			case ID_RADIO_TEL:
@@ -541,12 +540,14 @@
 	 * followed by one or more levels of organizational unit names.
 	 */
 	 
-	if (company || department)
+  if (company || department || office)
 	{
 		strbuf_append(vcard, "ORG:");
 		strbuf_append_escaped_wstr (vcard, company, flags);
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, department, flags);
+    strbuf_append_c            (vcard, ';');
+    strbuf_append_escaped_wstr (vcard, office, flags);
 		strbuf_append_crlf      (vcard);
 	}
 
@@ -1204,6 +1205,12 @@
 		if (separator)
 		{
 			if (separator[1]) {
+        char* separator2 = strchr(separator + 1, ';');
+        if (separator2)
+        {
+          add_string(parser, INDEX_OFFICE_LOC, type, separator2 + 1);
+          *separator2 = '\0';
+        }
         add_string(parser, INDEX_DEPARTMENT, type, separator + 1);
 			}
 			*separator = '\0';
@@ -1252,10 +1259,6 @@
   {
     add_string(parser, INDEX_ASSISTANT, type, value);
   }
-  else if (STR_EQUAL(name, "X-EVOLUTION-OFFICE"))
-  {
-    add_string(parser, INDEX_OFFICE_LOC, type, value);
-  }
 
 #if 0
 	else if (STR_EQUAL(name, ""))
--- ./lib/contact.c.Orig	2006-01-18 09:56:42.000000000 +0100
+++ ./lib/contact.c	2006-01-18 09:56:46.000000000 +0100
@@ -597,7 +597,7 @@
 
 	if (other_street || other_locality || other_postal_code || other_country)
 	{
-		strbuf_append_type(vcard, "ADR", "POSTAL", flags);
+    strbuf_append_type(vcard, "ADR", "OTHER", flags);
 		strbuf_append_escaped_wstr (vcard, NULL, flags); /* post office box */
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, NULL, flags); /* extended address */
@@ -1085,7 +1085,7 @@
 		char** address = strsplit(value, ';');
 		int where;
 
-		if (STR_IN_STR(type, "POSTAL"))
+    if (STR_IN_STR(type, "OTHER"))
 		        where = OTHER;
 		else if (STR_IN_STR(type, "WORK"))
 			where = WORK;
--- ./lib/contact.c.Orig	2006-01-18 10:05:05.000000000 +0100
+++ ./lib/contact.c	2006-01-18 10:05:31.000000000 +0100
@@ -559,12 +559,28 @@
 
 	if (home_street || home_locality || home_postal_code || home_country)
 	{
+    char *street = NULL;
+    char *extended = NULL;
+
+    if (home_street)
+    {
+      if (flags & RRA_CONTACT_UTF8)
+        street = wstr_to_utf8(home_street);
+      else
+        street = wstr_to_ascii(home_street);
+
+      extended = strstr(street, "\n");
+
+      if (extended)
+        extended++[-1] = '\0';
+    }
+
 		strbuf_append_type(vcard, "ADR", "HOME", flags);
 		strbuf_append_escaped_wstr (vcard, NULL, flags); /* post office box */
 		strbuf_append_c            (vcard, ';');
-		strbuf_append_escaped_wstr (vcard, NULL, flags); /* extended address */
+    strbuf_append_escaped      (vcard, extended, flags); /* extended address */
 		strbuf_append_c            (vcard, ';');
-		strbuf_append_escaped_wstr (vcard, home_street, flags);
+    strbuf_append_escaped      (vcard, street, flags);
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, home_locality, flags);
 		strbuf_append_c            (vcard, ';');
@@ -574,16 +590,35 @@
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, home_country, flags);
 		strbuf_append_crlf      (vcard);
+
+    if (street)
+      wstr_free_string(street);
 	}
 
 	if (work_street || work_locality || work_postal_code || work_country)
 	{
+    char *street = NULL;
+    char *extended = NULL;
+
+    if (work_street)
+    {
+      if (flags & RRA_CONTACT_UTF8)
+        street = wstr_to_utf8(work_street);
+      else
+        street = wstr_to_ascii(work_street);
+
+      extended = strstr(street, "\n");
+
+      if (extended)
+        extended++[-1] = '\0';
+    }
+
 		strbuf_append_type(vcard, "ADR", "WORK", flags);
 		strbuf_append_escaped_wstr (vcard, NULL, flags); /* post office box */
 		strbuf_append_c            (vcard, ';');
-		strbuf_append_escaped_wstr (vcard, NULL, flags); /* extended address */
+    strbuf_append_escaped      (vcard, extended, flags); /* extended address */
 		strbuf_append_c            (vcard, ';');
-		strbuf_append_escaped_wstr (vcard, work_street, flags);
+    strbuf_append_escaped      (vcard, street, flags);
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, work_locality, flags);
 		strbuf_append_c            (vcard, ';');
@@ -593,16 +628,35 @@
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, work_country, flags);
 		strbuf_append_crlf      (vcard);
+
+    if (street)
+      wstr_free_string(street);
 	}
 
 	if (other_street || other_locality || other_postal_code || other_country)
 	{
+    char *street = NULL;
+    char *extended = NULL;
+
+    if (other_street)
+    {
+      if (flags & RRA_CONTACT_UTF8)
+        street = wstr_to_utf8(other_street);
+      else
+        street = wstr_to_ascii(other_street);
+
+      extended = strstr(street, "\n");
+
+      if (extended)
+        extended++[-1] = '\0';
+    }
+
     strbuf_append_type(vcard, "ADR", "OTHER", flags);
 		strbuf_append_escaped_wstr (vcard, NULL, flags); /* post office box */
 		strbuf_append_c            (vcard, ';');
-		strbuf_append_escaped_wstr (vcard, NULL, flags); /* extended address */
+    strbuf_append_escaped      (vcard, extended, flags); /* extended address */
 		strbuf_append_c            (vcard, ';');
-		strbuf_append_escaped_wstr (vcard, other_street, flags);
+    strbuf_append_escaped      (vcard, street, flags);
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, other_locality, flags);
 		strbuf_append_c            (vcard, ';');
@@ -612,6 +666,9 @@
 		strbuf_append_c            (vcard, ';');
 		strbuf_append_escaped_wstr (vcard, other_country, flags);
 		strbuf_append_crlf      (vcard);
+
+    if (street)
+      wstr_free_string(street);
 	}
 
 
@@ -1103,7 +1160,15 @@
 		{
       if (address_index[i][where] && *address[i])
 			{
-        add_string(parser, address_index[i][where], type, address[i]);
+        if (i == 2 && *address[1])
+        {
+          char buf[strlen(address[1]) + strlen(address[2]) + 3];
+
+          snprintf(buf, sizeof(buf), "%s\\n%s", address[2], address[1]);
+
+          add_string(parser, address_index[i][where], type, buf);
+        } else
+          add_string(parser, address_index[i][where], type, address[i]);
 			}
 		}
 		
--- ./lib/contact.c.Orig	2006-01-20 17:40:47.000000000 +0100
+++ ./lib/contact.c	2006-01-20 17:41:31.000000000 +0100
@@ -41,6 +41,8 @@ static void strbuf_append_escaped(StrBuf
 		switch (*p)
 		{
 			case '\r': 				/* CR */
+      case 19: 		  		/* XOFF */
+      case 31: 		  		/* Unit separator */
 				/* ignore */
 				break;		
 
@@ -284,18 +286,16 @@ static bool rra_contact_to_vcard2(/*{{{*
         strbuf_append_date(vcard, "BDAY", &pFields[i].val.filetime);
         break;
       
-#if 0
 			case ID_NOTE:
 				{
 					unsigned j;
-					for (j = 0; j < pFields[i].val.blob.dwCount && pFields[i].val.blob.lpb[i]; j++)
+          for (j = 0; j < pFields[i].val.blob.dwCount && pFields[i].val.blob.lpb[j]; j++)
 						;
 
 					if (j == pFields[i].val.blob.dwCount)
 					{
 						strbuf_append(vcard, "NOTE:");
-						/* XXX: need to handle newlines! */
-						strbuf_append(vcard, (const char*)pFields[i].val.blob.lpb);
+            strbuf_append_escaped(vcard, pFields[i].val.blob.lpb, flags);
 						strbuf_append_crlf(vcard);
 					}
 					else
@@ -304,7 +304,6 @@ static bool rra_contact_to_vcard2(/*{{{*
 					}
 				}
 				break;
-#endif
 
 			case ID_SUFFIX:
 				suffix = pFields[i].val.lpwstr;
@@ -782,9 +781,6 @@ typedef struct _Parser
 
 typedef enum _field_index
 {
-/*
-  INDEX_NOTE,
-*/
   INDEX_SUFFIX,
   INDEX_FIRST_NAME,
   INDEX_WORK_TEL,
@@ -833,6 +829,7 @@ typedef enum _field_index
   INDEX_EMAIL,
   INDEX_EMAIL2,
   INDEX_EMAIL3,
+  INDEX_NOTE,
   ID_COUNT
 } field_index;
 
@@ -866,9 +863,6 @@ static uint32_t address_index[ADDRESS_FI
 
 static const uint32_t field_id[ID_COUNT] =
 {
-/*
-  ID_NOTE,
-*/
   ID_SUFFIX,
   ID_FIRST_NAME,
   ID_WORK_TEL,
@@ -916,7 +910,8 @@ static const uint32_t field_id[ID_COUNT]
   ID_OTHER_COUNTRY,
   ID_EMAIL,
   ID_EMAIL2,
-  ID_EMAIL3
+  ID_EMAIL3,
+  ID_NOTE,
 };
 
 static char* strdup_quoted_printable(const unsigned char* source)/*{{{*/
@@ -1055,6 +1050,36 @@ static void add_string(Parser* parser, u
   }
 }/*}}}*/
 
+static void add_blob(Parser* parser, uint32_t index, const char* type, char* data)/*{{{*/
+{
+  char* converted = NULL;
+  CEPROPVAL* field = &parser->fields[index];
+
+  assert(data);
+
+  if (field->propid & CEVT_FLAG_EMPTY)
+  {
+    field->propid = (field_id[index] << 16) | CEVT_BLOB;
+
+    if (STR_IN_STR(type, "QUOTED-PRINTABLE"))
+    {
+      data = converted = strdup_quoted_printable(data);
+      assert(data);
+    }
+  
+    unescape_string(data);
+    assert(data);
+ 
+    field->val.blob.dwCount = strlen(data);
+    field->val.blob.lpb = malloc(field->val.blob.dwCount);
+    assert(field->val.blob.lpb);
+    memcpy(field->val.blob.lpb, data, field->val.blob.dwCount);
+  
+    if (converted)
+      free(converted);
+  }
+}/*}}}*/
+
 static bool parser_handle_field(/*{{{*/
 		Parser* parser,
 		char* name, 
@@ -1324,6 +1349,10 @@ static bool parser_handle_field(/*{{{*/
   {
     add_string(parser, INDEX_ASSISTANT, type, value);
   }
+  else if (STR_EQUAL(name, "NOTE"))
+  {
+    add_blob(parser, INDEX_NOTE, type, value);
+  }
 
 #if 0
 	else if (STR_EQUAL(name, ""))
@@ -1492,6 +1521,10 @@ static bool rra_contact_from_vcard2(/*{{
       field->propid = (field_id[count] << 16) |
           CEVT_FLAG_EMPTY | CEVT_FILETIME;
       break;
+    case INDEX_NOTE:
+      field->propid = (field_id[count] << 16) |
+          CEVT_FLAG_EMPTY | CEVT_BLOB;
+      break;
     default:
       field->propid = (field_id[count] << 16) |
           CEVT_FLAG_EMPTY | CEVT_LPWSTR;
--- ./lib/contact.c.Orig	2006-01-20 17:51:58.000000000 +0100
+++ ./lib/contact.c	2006-01-20 17:52:04.000000000 +0100
@@ -513,6 +513,12 @@ static bool rra_contact_to_vcard2(/*{{{*
 				strbuf_append_crlf(vcard);
 				break;
 
+      case ID_CHILDREN:
+        strbuf_append(vcard, "X-SYNCE-CHILDREN:");
+        strbuf_append_escaped_wstr(vcard, pFields[i].val.lpwstr, flags);
+        strbuf_append_crlf(vcard);
+        break;
+
 			default:
 				synce_warning("Did not handle field with ID %04x", pFields[i].propid >> 16);
 				break;
@@ -801,9 +807,7 @@ typedef enum _field_index
   INDEX_CATEGORY,
   INDEX_ASSISTANT,
   INDEX_ASSISTANT_TEL,
-/*
   INDEX_CHILDREN,
-*/
   INDEX_WORK2_TEL,
   INDEX_WEB_PAGE,
   INDEX_PAGER,
@@ -883,9 +887,7 @@ static const uint32_t field_id[ID_COUNT]
   ID_CATEGORY,
   ID_ASSISTANT,
   ID_ASSISTANT_TEL,
-/*
   ID_CHILDREN,
-*/
   ID_WORK2_TEL,
   ID_WEB_PAGE,
   ID_PAGER,
@@ -1353,6 +1355,10 @@ static bool parser_handle_field(/*{{{*/
   {
     add_blob(parser, INDEX_NOTE, type, value);
   }
+  else if (STR_EQUAL(name, "X-SYNCE-CHILDREN"))
+  {
+    add_string(parser, INDEX_CHILDREN, type, value);
+  }
 
 #if 0
 	else if (STR_EQUAL(name, ""))

Reply via email to