Index: lib/Makefile.am =================================================================== RCS file: /cvsroot/synce/rra/lib/Makefile.am,v retrieving revision 1.18 retrieving revision 1.19 diff -u -b -B -u -p -r1.18 -r1.19 --- lib/Makefile.am 17 Aug 2004 16:13:21 -0000 1.18 +++ lib/Makefile.am 22 Jul 2005 07:34:05 -0000 1.19 @@ -1,5 +1,5 @@ ## useful flags -AM_CFLAGS = -g -Wall -Wsign-compare -Wno-long-long -Werror -ansi @CFLAGS@ -I.. +AM_CFLAGS = -g -Wall -Wsign-compare -Wno-long-long -ansi @CFLAGS@ -I.. ## @APPLE_CFLAGS@ includedir = @includedir@/rra Index: lib/common_handlers.c =================================================================== RCS file: /cvsroot/synce/rra/lib/common_handlers.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -b -B -u -p -r1.9 -r1.10 --- lib/common_handlers.c 2 May 2004 11:16:17 -0000 1.9 +++ lib/common_handlers.c 6 Aug 2005 13:11:33 -0000 1.10 @@ -1,4 +1,4 @@ -/* $Id: common_handlers.c,v 1.9 2004/05/02 11:16:17 twogood Exp $ */ +/* $Id: common_handlers.c,v 1.10 2005/08/06 13:11:33 twogood Exp $ */ #define _GNU_SOURCE 1 #include "common_handlers.h" #include "parser.h" @@ -203,7 +203,11 @@ bool on_mdir_line_description(Parser* p, strbuf_append_c(note, *q); } - success = parser_add_blob(p, ID_NOTES, note->buffer, note->length); + success = parser_add_blob( + p, + ID_NOTES, + (const uint8_t*)note->buffer, + note->length); if (parser_utf8(p)) free(source); Index: lib/contact.c =================================================================== RCS file: /cvsroot/synce/rra/lib/contact.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -b -B -u -p -r1.22 -r1.23 --- lib/contact.c 13 May 2005 11:35:28 -0000 1.22 +++ lib/contact.c 22 Jul 2005 07:30:56 -0000 1.23 @@ -1,4 +1,4 @@ -/* $Id: contact.c,v 1.22 2005/05/13 11:35:28 twogood Exp $ */ +/* $Id: contact.c,v 1.23 2005/07/22 07:30:56 twogood Exp $ */ #define _GNU_SOURCE 1 #include "contact.h" #include "contact_ids.h" @@ -67,6 +67,52 @@ static void strbuf_append_escaped(StrBuf } }/*}}}*/ +/* + More or less the same as strbuf_append_escaped(), but specialized for comma separated lists +*/ +static void strbuf_append_comma_separated(StrBuf* result, char* source, uint32_t flags)/*{{{*/ +{ + char* p; + + if (!source) + return; + + for (p = source; *p; p++) + { + switch (*p) + { + case '\r': /* CR */ + /* ignore */ + break; + + case '\n': /* LF */ + strbuf_append_c(result, '\\'); + strbuf_append_c(result, 'n'); + break; + + case '\\': + strbuf_append_c(result, '\\'); + strbuf_append_c(result, *p); + break; + + case ',': + strbuf_append_c(result, ','); + while (*(p+1)==' ') /* skip blanks after comma */ + p++; + break; + + case ';': + if (flags & RRA_CONTACT_VERSION_3_0) + strbuf_append_c(result, '\\'); + /* fall through */ + + default: + strbuf_append_c(result, *p); + break; + } + } +}/*}}}*/ + void strbuf_append_escaped_wstr(StrBuf* strbuf, WCHAR* wstr, uint32_t flags)/*{{{*/ { if (wstr) @@ -83,6 +129,22 @@ void strbuf_append_escaped_wstr(StrBuf* } }/*}}}*/ +void strbuf_append_comma_separated_wstr(StrBuf* strbuf, WCHAR* wstr, uint32_t flags)/*{{{*/ +{ + if (wstr) + { + char* str = NULL; + + if (flags & RRA_CONTACT_UTF8) + str = wstr_to_utf8(wstr); + else + str = wstr_to_ascii(wstr); + + strbuf_append_comma_separated(strbuf, str, flags); + wstr_free_string(str); + } +}/*}}}*/ + /* * value should be a comma-separated list of types */ @@ -313,7 +375,7 @@ static bool rra_contact_to_vcard2(/*{{{* case ID_CATEGORY: strbuf_append(vcard, "CATEGORIES:"); - strbuf_append_escaped_wstr(vcard, pFields[i].val.lpwstr, flags); + strbuf_append_comma_separated_wstr(vcard, pFields[i].val.lpwstr, flags); strbuf_append_crlf(vcard); break; @@ -818,8 +880,10 @@ static bool parser_handle_field(/*{{{*/ Parser* parser, char* name, char* type, - char* value) + char* value, + int nth) { + bool success = false; #if VERBOSE @@ -848,7 +912,7 @@ static bool parser_handle_field(/*{{{*/ } }/*}}}*/ - if (parser->level != 1) + if (parser->level != 1 && nth==0) { synce_error("Not within BEGIN:VCARD / END:VCARD"); goto exit; @@ -931,11 +995,17 @@ static bool parser_handle_field(/*{{{*/ /* TODO: make type uppercase */ if (STR_IN_STR(type, "HOME")) { + if (nth==1) add_string(parser, fax ? ID_HOME_FAX : ID_HOME_TEL, type, value); + else + add_string(parser, ID_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); + else + add_string(parser, ID_WORK2_TEL, type, value); } else if (STR_IN_STR(type, "CELL")) { @@ -965,7 +1035,18 @@ static bool parser_handle_field(/*{{{*/ type, name); } + switch (nth) + { + case 1: add_string(parser, ID_EMAIL, type, value); + break; + case 2: + add_string(parser, ID_EMAIL2, type, value); + break; + case 3: + add_string(parser, ID_EMAIL3, type, value); + break; + } }/*}}}*/ else if (STR_EQUAL(name, "URL"))/*{{{*/ { @@ -1064,6 +1145,89 @@ exit: }/*}}}*/ /* + * 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)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=0) { + fs[slot].name = data->name; + fs[slot].type = data->type; + fs[slot].value = data->value; + fs[slot].pref = data->pref; + (*count)++; + } +}/*}}}*/ + +/* + * process the queued fields. + */ +void process_queue(/*{{{*/ + Parser *parser, + struct FieldStrings *fs, + 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; iname = 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, - strndup(name, name_end - name), - type ? strndup(type, type_end - type) : strdup(""), - strndup(value, value_end - value)); - + tmp_field->name, + tmp_field->type, + tmp_field->value, + 0); + } state = VCARD_STATE_NEWLINE; } p++; @@ -1167,6 +1360,10 @@ static bool rra_contact_from_vcard2(/*{{ } } + process_queue(&parser, tel_work, count_tel_work); + process_queue(&parser, tel_home, count_tel_home); + process_queue(&parser, email, count_email); + *field_count = parser.field_index; success = true; Index: lib/contact.h =================================================================== RCS file: /cvsroot/synce/rra/lib/contact.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -b -B -u -p -r1.1 -r1.2 --- lib/contact.h 8 Dec 2003 09:44:02 -0000 1.1 +++ lib/contact.h 22 Jul 2005 07:30:57 -0000 1.2 @@ -1,4 +1,4 @@ -/* $Id: contact.h,v 1.1 2003/12/08 09:44:02 twogood Exp $ */ +/* $Id: contact.h,v 1.2 2005/07/22 07:30:57 twogood Exp $ */ #ifndef __contact_h__ #define __contact_h__ @@ -41,6 +41,14 @@ bool rra_contact_from_vcard( uint32_t flags); #endif /* SWIG */ +struct FieldStrings +{ + char* name; + char* type; + char* value; + bool pref; +}; + #define rra_contact_free_vcard(p) if (p) free(p) #define rra_contact_free_data(p) if (p) free(p) Index: lib/contact_ids.h =================================================================== RCS file: /cvsroot/synce/rra/lib/contact_ids.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -b -B -u -p -r1.4 -r1.5 --- lib/contact_ids.h 16 Feb 2005 14:36:12 -0000 1.4 +++ lib/contact_ids.h 22 Jul 2005 07:30:57 -0000 1.5 @@ -59,5 +59,9 @@ #define ID_EMAIL2 0x4093 #define ID_EMAIL3 0x40a3 +#define MAX_TEL_WORK 2 +#define MAX_TEL_HOME 2 +#define MAX_EMAIL 3 + #endif Index: src/Makefile.am =================================================================== RCS file: /cvsroot/synce/rra/src/Makefile.am,v retrieving revision 1.18 retrieving revision 1.19 diff -u -b -B -u -p -r1.18 -r1.19 --- src/Makefile.am 18 Apr 2004 20:13:44 -0000 1.18 +++ src/Makefile.am 22 Jul 2005 07:34:05 -0000 1.19 @@ -1,5 +1,5 @@ ## useful flags -AM_CFLAGS = -g -Wall -Wsign-compare -Wno-long-long -Werror -ansi @CFLAGS@ -I../lib +AM_CFLAGS = -g -Wall -Wsign-compare -Wno-long-long -ansi @CFLAGS@ -I../lib LDADD = -L../lib ../lib/librra.la bin_PROGRAMS = synce-matchmaker