1 // ---------------------------------------------------------- -*- c++ -*-
2 // bbdb parser and converter
3 // supported output format: vcards abook gnokii csv
5 // Copyright (C) 1994-2003: Pierre Aubert pierre.aubert@free.fr
6 // Code below is dirty. Don't take model on it.
8 // V1.21 add abook format
9 // V1.20 adapt for g++-3
10 // ----------------------------------------------------------------------
12 // This library is free software; you can redistribute it and/or
13 // modify it under the terms of the GNU Library General Public
14 // License as published by the Free Software Foundation; either
15 // version 2 of the License, or (at your option) any later version.
17 // This library is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 // Library General Public License for more details.
22 // You should have received a copy of the GNU Library General Public
23 // License along with this library; if not, write to the
24 // Free Software Foundation, Inc., 59 Temple Place - Suite 330,
25 // Boston, MA 02111-1307, USA.
27 // ----------------------------------------------------------------------
36 // horrible global variable
39 // hold datas from a bbdb record
41 enum { NAME, FORNAME, AKA, COMPANY, PHONES, ADRESSES, NET, NOTES };
43 typedef std::vector<std::string> storage_t;
57 print( std::string const& l, int jb, int je ) {
58 char wl[5] = { 27, '[' , '5' , 'm', 0 };
59 char wr[5] = { 27, '[' , '0' , 'm', 0 };
61 for( i=0 ; i<jb ; ++i )
64 for( i=jb ; i<je ; ++i )
67 for( i=je ; i<l.size() ; ++i )
70 std::cerr << std::endl;
74 // used for translation between format
76 const char * const my_val;
77 const char * const my_trans;
80 // parse 1 line of bbdb format, of course it is easier in elisp :)
82 parse( int const debug, int const tokmax, char const first_char, std::string const& line ) {
92 if( line[jb] == first_char )
97 // jb pointe sur le premier caractere du token
98 // je pointe sur le premier caractere apres la fin du token
100 // look for beginning of token
102 while( jb < l && c != '(' && c != '[' && c != '"' && c != ' ' && !isalpha(c) )
107 char state = line[jb];
108 // look for end of token
114 for( ; je < l ; ++je ) {
116 trace::print(line,jb,je);
117 if( line[je] == ')' ) {
119 if( cnt_lpar == 0 ) {
124 if( line[je] == '(' )
133 for( ; je < l ; ++je ) {
135 trace::print(line,jb,je);
136 if( line[je] == ']' ) {
138 if( cnt_lbra == 0 ) {
143 if( line[je] == '[' )
151 while( je < l && line[je] != state )
159 while( je < l && line[je] != state )
164 case 'n': // nil && notes
168 if( line[je] == 'i' )
169 while( je < l && line[je] != ' ' )
172 while( je < l && line[je] != '.' )
178 case 'c': // creation-date
179 case 't': // timestamp
184 while( je < l && line[je] != '.' )
191 trace::print(line,jb,je);
193 if( line[jb] == '"' )
194 id->my_d.push_back( line.substr(jb+1,je-jb-2) );
196 id->my_d.push_back( line.substr(jb,je-jb) );
211 // ----------------------------------------------------------------------
213 // ----------------------------------------------------------------------
214 void tognokii( std::string const& l )
216 Id * id = parse( trace::NONE, 9, '[', l);
219 std::cerr << "Broken line ==>" << l << "<==" << std::endl;
223 Id::storage_t const& s = id->my_d;
226 if( s[Id::PHONES].compare( "nil" ) != 0 ) {
227 Id * phones = new Id;
228 phones = parse( trace::NONE, 1, '(', s[Id::PHONES] );
229 if( phones == NULL ) {
230 std::cerr << "can't parse phones ==>" << s[Id::PHONES] << "<==" << std::endl;
235 std::cout << s[Id::NAME] << '\t' << s[Id::FORNAME] << '\t';
238 for( int cur_phone = 0 ; cur_phone < phones->my_d.size() ; ++cur_phone ) {
239 phone = parse( trace::NONE, 1, '[', phones->my_d[cur_phone] );
241 if( phone != NULL ) {
242 std::cout << phone->my_d[1];
246 std::cout << std::endl;
256 // ----------------------------------------------------------------------
258 // ----------------------------------------------------------------------
259 static two_strings VCARDPhoneTypes [] =
265 { "personnel", "home" },
266 { "personel", "home" },
267 { "monchat", "home" },
271 { "travail", "work" },
278 { "voice", "voice" },
282 { "portable", "cell" },
284 { "video", "video" },
285 { "pager", "pager" },
286 { "tatoo", "pager" },
287 { "voiture", "car" },
288 { "modem", "modem" },
294 struct VCARDPhoneTypesMap {
295 static two_strings const my_default [];
298 operator()(const char* s1, const char* s2) const {
299 return strcmp(s1, s2) < 0;
303 VCARDPhoneTypesMap() {
304 unsigned short i = 0;
305 while( VCARDPhoneTypes[i].my_val != 0 ) {
306 my_h[ VCARDPhoneTypes[i].my_val ] = VCARDPhoneTypes[i].my_trans;
311 typedef std::map<const char*,const char*,ltstr> hash_t;
315 two_strings const VCARDPhoneTypesMap::my_default [] =
323 static VCARDPhoneTypesMap vcard_phone_types_map;
325 void tovcard( std::string const& l )
327 Id * id = parse( trace::NONE, 9,'[',l);
330 std::cerr << "Broken line ==>" << l << "<==" << std::endl;
334 Id::storage_t const& s = id->my_d;
336 // std::string filename( s[Id::FORNAME] + "_" + s[Id::NAME] + ".vcf" );
337 // std::ofstream os( filename.c_str() );
339 std::cout << "BEGIN:VCARD" << std::endl;
341 std::cout << "FN:" << s[Id::NAME] << ' ' << s[Id::FORNAME] << std::endl;
342 std::cout << "N:" << s[Id::FORNAME] << ';' << s[Id::NAME] << std::endl;
344 if( s[Id::PHONES].compare( "nil" ) != 0 ) {
345 Id * phones = new Id;
346 phones = parse( trace::NONE, 1, '(', s[Id::PHONES] );
347 if( phones == NULL ) {
348 std::cerr << "can't parse phones ==>" << s[Id::PHONES] << "<==" << std::endl;
354 for( int cur_phone = 0 ; cur_phone < phones->my_d.size() ; ++cur_phone ) {
355 phone = parse( trace::NONE, 1, '[', phones->my_d[cur_phone] );
356 if( phone != NULL ) {
358 if( phone->my_d[0].find_first_of( "0123456789 _-:;," ) == phone->my_d[0].npos ) {
359 VCARDPhoneTypesMap::hash_t::iterator it;
360 if( (it=vcard_phone_types_map.my_h.find( const_cast<char*>(phone->my_d[0].c_str()))) != vcard_phone_types_map.my_h.end() ) {
361 std::cout << ";" << it->second;
363 std::cout << ";" << vcard_phone_types_map.my_default[0].my_trans;
366 if( phone->my_d.size() > 1 )
367 std::cout << ':' << phone->my_d[1] << std::endl;
369 std::cerr << "phone size is less than 2" << std::endl;
376 if( s[Id::ADRESSES].compare( "nil" ) != 0 ) {
377 Id * adresses = new Id;
378 adresses = parse( trace::NONE, 1, '(', s[Id::ADRESSES] );
379 if( adresses == NULL ) {
380 std::cerr << "can't parse adresses ==>" << s[Id::ADRESSES] << "<==" << std::endl;
385 Id * adresse = new Id;
386 for( int cur_adresse = 0 ; cur_adresse < adresses->my_d.size() ; ++cur_adresse ) {
387 adresse = parse( trace::NONE, 1, '[', adresses->my_d[cur_adresse] );
388 if( adresse != NULL ) {
390 Id * fields = new Id;
391 fields = parse( trace::NONE, 1, '(' , adresse->my_d[1] );
392 if( fields != NULL ) {
393 std::string const& town = adresse->my_d[2];
394 std::string const& state = adresse->my_d[3];
395 std::string const& postal = adresse->my_d[4];
396 std::string const& country = adresse->my_d[5];
398 if( adresse->my_d[0].size() > 0 )
399 if( adresse->my_d[0].find_first_of( "0123456789 _-:;," ) == adresse->my_d[0].npos )
400 std::cout << ";TYPE=" << adresse->my_d[0];
401 std::cout << ':' << ';' << ';' << fields->my_d[0];
402 for( int i=1 ; i<fields->my_d.size() ; ++i )
403 std::cout << ',' << fields->my_d[i] ;
404 std::cout << ';' << town << ';' << state << ';' << postal << ';' << country << ';' << std::endl;
407 std::cerr << "unknown adresse format for ==>" << adresse->my_d[1] << "<<=" << std::endl;
416 if( s[Id::NET].compare("nil") != 0 ) {
418 nets = parse( trace::NONE, 1, '(', s[Id::NET] );
420 std::cerr << "can't parse nets ==>" << s[Id::NET] << "<==" << std::endl;
425 std::cout << "EMAIL;INTERNET;PREF:" << nets->my_d[0] << std::endl;
426 for( int cur_net = 1 ; cur_net < nets->my_d.size() ; ++cur_net )
427 std::cout << "EMAIL;INTERNET:" << nets->my_d[cur_net] << std::endl;
432 if( s[Id::COMPANY].compare("nil") != 0 )
433 std::cout << "ORG:" << s[Id::COMPANY] << std::endl;
435 if( s[Id::AKA].compare("nil") != 0 ) {
437 if( s[Id::AKA].find('(') == s[Id::AKA].npos )
438 std::cout << "NICKNAME:" << s[Id::AKA] << std::endl;
441 akas = parse( trace::NONE, 1, '(', s[Id::AKA] );
443 std::cerr << "can't parse akas ==>" << s[Id::AKA] << "<==" << std::endl;
449 for( int cur_aka = 0 ; cur_aka < akas->my_d.size() ; ++cur_aka ) {
450 aka = parse( trace::NONE, 1, '(', akas->my_d[cur_aka] );
452 std::cout << "NICKNAME:" << aka->my_d[0] << std::endl;
459 if( s[Id::NOTES].compare("nil") != 0 ) {
461 if( s[Id::NOTES].find('(') == s[Id::NOTES].npos )
462 std::cout << "NOTE:" << s[Id::NOTES] << std::endl;
464 notes = parse( trace::NONE, 1, '(', s[Id::NOTES] );
465 if( notes == NULL ) {
466 std::cerr << "can't parse notes ==>" << s[Id::NOTES] << "<==" << std::endl;
472 for( int cur_note = 0 ; cur_note < notes->my_d.size() ; ++cur_note ) {
473 note = parse( trace::NONE, 1, '(', notes->my_d[cur_note] );
475 std::string const& t = note->my_d[0];
476 std::string const& r = note->my_d[1];
478 if( t.find("creation-date") != t.npos || t.find("timestamp") != t.npos ) {
480 } else if( t.find("www") != t.npos || t.find("http") != t.npos ) {
481 std::cout << "URL:" << r << std::endl;
482 } else if( t.find("notes") != t.npos ) {
483 std::cout << "NOTE:" << r << std::endl;
484 } else if( t.find("icq") != t.npos ) {
485 std::cout << "NOTE: ICQ #" << r << std::endl;
486 } else if( t.find("msn") != t.npos ) {
487 std::cout << "NOTE: MSN " << r << std::endl;
489 std::cerr << "drop notes: " << t << " for " << s[Id::NAME] << std::endl;
498 std::cout << "END:VCARD" << std::endl << std::endl;
504 // ----------------------------------------------------------------------
506 // ----------------------------------------------------------------------
508 static two_strings ABOOKPhoneTypes [] =
512 { "perso", "phone" },
513 { "personnel", "phone" },
514 { "personel", "phone" },
515 { "monchat", "phone" },
518 { "work", "workphone" },
519 { "travail", "workphone" },
520 { "paris", "workphone" },
521 { "lyon", "workphone" },
522 { "issy", "workphone" },
523 { "insa", "workphone" },
524 { "woo", "workphone" },
525 { "fac", "workphone" },
526 { "voice", "phone" },
529 { "cell", "mobile" },
530 { "portable", "mobile" },
532 { "video", "phone" },
533 { "pager", "phone" },
534 { "tatoo", "phone" },
535 { "voiture", "phone" },
536 { "modem", "phone" },
542 struct ABOOKPhoneTypesMap {
543 static two_strings const my_default [];
546 operator()(const char* s1, const char* s2) const {
547 return strcmp(s1, s2) < 0;
551 ABOOKPhoneTypesMap() {
552 unsigned short i = 0;
553 while( ABOOKPhoneTypes[i].my_val != 0 ) {
554 my_h[ ABOOKPhoneTypes[i].my_val ] = ABOOKPhoneTypes[i].my_trans;
559 typedef std::map<const char*,const char*,ltstr> hash_t;
563 two_strings const ABOOKPhoneTypesMap::my_default [] = {
569 static ABOOKPhoneTypesMap abook_phone_types_map;
571 void toabook( std::string const& l ) {
572 Id * id = parse( trace::NONE, 9,'[',l);
575 std::cerr << "Broken line ==>" << l << "<==" << std::endl;
579 Id::storage_t const& s = id->my_d;
581 std::cout << '[' << counter << ']' << std::endl;
584 std::cout << "name=" << s[Id::FORNAME] << ' ' << s[Id::NAME] << std::endl;
586 if( s[Id::NET].compare("nil") != 0 ) {
588 nets = parse( trace::NONE, 1, '(', s[Id::NET] );
590 std::cerr << "can't parse nets ==>" << s[Id::NET] << "<==" << std::endl;
595 std::cout << "email=" << nets->my_d[0];
596 for( int cur_net = 1 ; cur_net < nets->my_d.size() ; ++cur_net ) {
597 std::cout << "," << nets->my_d[cur_net];
599 std::cout << std::endl;
604 if( s[Id::PHONES].compare( "nil" ) != 0 ) {
605 Id * phones = new Id;
606 phones = parse( trace::NONE, 1, '(', s[Id::PHONES] );
607 if( phones == NULL ) {
608 std::cerr << "can't parse phones ==>" << s[Id::PHONES] << "<==" << std::endl;
614 for( int cur_phone = 0 ; cur_phone < phones->my_d.size() ; ++cur_phone ) {
615 phone = parse( trace::NONE, 1, '[', phones->my_d[cur_phone] );
616 if( phone != NULL ) {
617 if( phone->my_d[0].find_first_of( "0123456789 _-:;," ) == phone->my_d[0].npos ) {
618 ABOOKPhoneTypesMap::hash_t::iterator it;
619 if( (it=abook_phone_types_map.my_h.find( const_cast<char*>(phone->my_d[0].c_str())))
620 != abook_phone_types_map.my_h.end() ) {
621 std::cout << it->second;
623 std::cout << abook_phone_types_map.my_default[0].my_trans;
626 if( phone->my_d.size() > 1 )
627 std::cout << '=' << phone->my_d[1] << std::endl;
629 std::cerr << "phone size is less than 2" << std::endl;
636 if( s[Id::ADRESSES].compare( "nil" ) != 0 ) {
637 Id * adresses = new Id;
638 adresses = parse( trace::NONE, 1, '(', s[Id::ADRESSES] );
639 if( adresses == NULL ) {
640 std::cerr << "can't parse adresses ==>" << s[Id::ADRESSES] << "<==" << std::endl;
645 Id * adresse = new Id;
646 for( int cur_adresse = 0 ; cur_adresse < adresses->my_d.size() ; ++cur_adresse ) {
647 adresse = parse( trace::NONE, 1, '[', adresses->my_d[cur_adresse] );
648 if( adresse != NULL ) {
650 Id * fields = new Id;
651 fields = parse( trace::NONE, 1, '(' , adresse->my_d[1] );
652 if( fields != NULL ) {
653 std::string const& town = adresse->my_d[2];
654 std::string const& state = adresse->my_d[3];
655 std::string const& postal = adresse->my_d[4];
656 std::string const& country = adresse->my_d[5];
658 std::cout << "address=";
659 for( int i=0 ; i<fields->my_d.size() ; ++i )
660 std::cout << fields->my_d[i] << ' ';
661 std::cout << std::endl;
663 std::cout << "city=" << town << std::endl;
664 std::cout << "state=" << state << std::endl;
665 std::cout << "zip=" << postal << std::endl;
666 std::cout << "country=" << country << std::endl;
668 std::cerr << "unknown adresse format for ==>" << adresse->my_d[1] << "<<=" << std::endl;
677 if( s[Id::AKA].compare("nil") != 0 )
680 if( s[Id::AKA].find('(') == s[Id::AKA].npos )
682 std::cout << "nick=" << s[Id::AKA] << std::endl;
687 if( s[Id::NOTES].compare("nil") != 0 ) {
689 if( s[Id::NOTES].find('(') == s[Id::NOTES].npos ) {
690 std::cout << "notes=" << s[Id::NOTES] << std::endl;
692 notes = parse( trace::NONE, 1, '(', s[Id::NOTES] );
693 if( notes == NULL ) {
694 std::cerr << "can't parse notes ==>" << s[Id::NOTES] << "<==" << std::endl;
700 for( int cur_note = 0 ; cur_note < notes->my_d.size() ; ++cur_note ) {
701 note = parse( trace::NONE, 1, '(', notes->my_d[cur_note] );
704 std::string const& t = note->my_d[0];
705 std::string const& r = note->my_d[1];
707 if( t.find("creation-date") != t.npos || t.find("timestamp") != t.npos ) {
709 } else if( t.find("www") != t.npos || t.find("http") != t.npos ) {
710 std::cout << "url=" << r << std::endl;
711 } else if( t.find("notes") != t.npos ) {
712 std::cout << "note=" << r << std::endl;
713 } else if( t.find("icq") != t.npos ) {
714 std::cout << "note=icq #" << r << std::endl;
715 } else if( t.find("msn") != t.npos ) {
716 std::cout << "note=msn" << r << std::endl;
718 std::cerr << "drop notes: " << t << " for " << s[Id::NAME] << std::endl;
727 std::cout << std::endl;
731 // ----------------------------------------------------------------------
733 // ----------------------------------------------------------------------
734 void tocsv( std::string const& l )
736 char const sep = ',';
737 char const quo = '"';
739 Id * id = parse( trace::NONE, 9,'[',l);
743 std::cerr << "Broken line ==>" << l << "<==" << std::endl;
747 Id::storage_t const& s = id->my_d;
749 // "First Name","Last Name","Display Name"
750 std::cout << quo << s[Id::NAME] << quo << sep;
751 std::cout << quo << s[Id::FORNAME] << quo << sep;
752 std::cout << quo << s[Id::FORNAME] << ' ' << s[Id::NAME] << quo << sep;
756 if( s[Id::AKA].compare("nil") != 0 )
759 if( s[Id::AKA].find('(') == s[Id::AKA].npos )
761 std::cout << quo << s[Id::AKA] << quo << sep ;
765 akas = parse( trace::NONE, 1, '(', s[Id::AKA] );
768 std::cerr << "can't parse akas ==>" << s[Id::AKA] << "<==" << std::endl;
774 aka = parse( trace::NONE, 1, '(', akas->my_d[0] );
777 s_aka = quo + aka->my_d[0] + quo;
783 std::cout << s_aka << sep;
785 // "E-mail","Secondary E-mail"
786 std::string s_email1;
787 std::string s_email2;
788 if( s[Id::NET].compare("nil") != 0 )
791 nets = parse( trace::NONE, 1, '(', s[Id::NET] );
794 std::cerr << "can't parse nets ==>" << s[Id::NET] << "<==" << std::endl;
799 s_email1 = quo + nets->my_d[0] + quo;
800 if( nets->my_d.size() > 1 )
802 s_email2 = quo + nets->my_d[1] + quo;
806 std::cout << s_email1 << sep << s_email2 << sep;
808 // "Business Phone","Home Phone","Fax Phone","Pager","Mobile Phone"
809 std::string p_business;
813 std::string p_mobile;
815 if( s[Id::PHONES].compare( "nil" ) != 0 )
817 Id * phones = new Id;
818 phones = parse( trace::NONE, 1, '(', s[Id::PHONES] );
821 std::cerr << "can't parse phones ==>" << s[Id::PHONES] << "<==" << std::endl;
828 for( cur_phone = 0 ; cur_phone < std::min(size_t(5),phones->my_d.size()) ; ++cur_phone )
830 phone = parse( trace::NONE, 1, '[', phones->my_d[cur_phone] );
835 if( phone->my_d[0].find_first_of( "0123456789 _-:;," ) == phone->my_d[0].npos )
837 ABOOKPhoneTypesMap::hash_t::iterator it;
838 if( (it=abook_phone_types_map.my_h.find( const_cast<char*>(phone->my_d[0].c_str())))
839 != abook_phone_types_map.my_h.end() )
845 trans = abook_phone_types_map.my_default[0].my_trans;
848 if( trans.find("home") != trans.npos )
850 p_home = quo + phone->my_d[1] + quo ;
852 else if( trans.find("work") != trans.npos )
854 p_business = quo + phone->my_d[1] + quo ;
856 else if( trans.find("cell") != trans.npos )
858 p_mobile = quo + phone->my_d[1] + quo ;
860 else if( trans.find("fax") != trans.npos )
862 p_fax = quo + phone->my_d[1] + quo ;
864 else if( trans.find("pager") != trans.npos )
866 p_pager = quo + phone->my_d[1] + quo ;
870 if( p_home.size() == 0 )
872 p_home = quo + phone->my_d[1] + quo ;
880 std::cout << p_business << sep
886 // "Home Street 1","Home Street 2","Home City","Home State","Home Postal Code","Home Country",
887 // "Business Street 1","Business Street 2","Business City","Business State","Business Postal Code","Business Country"
888 if( s[Id::ADRESSES].compare( "nil" ) != 0 )
890 Id * adresses = new Id;
891 adresses = parse( trace::NONE, 1, '(', s[Id::ADRESSES] );
892 if( adresses == NULL )
894 std::cerr << "can't parse adresses ==>" << s[Id::ADRESSES] << "<==" << std::endl;
899 Id * adresse = new Id;
901 for( cur_adresse = 0 ; cur_adresse < std::min(size_t(2),adresses->my_d.size()) ; ++cur_adresse )
903 adresse = parse( trace::NONE, 1, '[', adresses->my_d[cur_adresse] );
905 if( adresse != NULL )
908 Id * fields = new Id;
909 fields = parse( trace::NONE, 1, '(' , adresse->my_d[1] );
912 std::string const& town = adresse->my_d[2];
913 std::string const& state = adresse->my_d[3];
914 std::string const& postal = adresse->my_d[4];
915 std::string const& country = adresse->my_d[5];
917 // if( adresse->my_d[0].size() > 0 )
919 // if( adresse->my_d[0].find_first_of( "0123456789 _-:;," ) ==
920 // adresse->my_d[0].npos )
922 // std::cout << ";TYPE=" << adresse->my_d[0];
926 for( i=0 ; i<std::min(size_t(2),fields->my_d.size()) ; ++i )
927 std::cout << quo << fields->my_d[i] << quo << sep;
928 for( i=std::min(size_t(2),fields->my_d.size()) ; i<2; ++i )
930 std::cout << quo << town << quo << sep
931 << quo << state << quo << sep
932 << quo << postal << quo << sep
933 << quo << country << quo << sep;
937 std::cerr << "unknown adresse format for ==>" << adresse->my_d[1]
938 << "<<=" << std::endl;
943 for( cur_adresse = std::min(size_t(2),adresses->my_d.size()) ; cur_adresse<2; ++cur_adresse )
945 std::cout << sep << sep << sep << sep << sep << sep;
952 std::cout << sep << sep << sep << sep << sep << sep
953 << sep << sep << sep << sep << sep << sep;
956 // "Job Title","Department","Company"
958 std::string s_departement;
959 std::string s_company;
960 if( s[Id::COMPANY].compare("nil") != 0 )
962 s_company = quo + s[Id::COMPANY] + quo;
964 std::cout << s_title << sep
965 << s_departement << sep
968 // "Web Page 1","Web Page 2","Birth Year","Birth Month","Birth Day","User Field 1","User Field 2","User Field 3","User Field 4","Notes"
972 std::string n_bmonth;
974 std::string n_user1; // icq
975 std::string n_user2; // im
980 if( s[Id::NOTES].compare("nil") != 0 )
983 if( s[Id::NOTES].find('(') == s[Id::NOTES].npos )
985 n_note = quo + s[Id::NOTES] + quo;
989 notes = parse( trace::NONE, 1, '(', s[Id::NOTES] );
992 std::cerr << "can't parse notes ==>" << s[Id::NOTES] << "<==" ;
999 for( cur_note = 0 ; cur_note < std::min(size_t(10),notes->my_d.size()) ; ++cur_note )
1001 note = parse( trace::NONE, 1, '(', notes->my_d[cur_note] );
1005 std::string const& t = note->my_d[0];
1006 std::string const& r = note->my_d[1];
1008 if( t.find("www") != t.npos || t.find("http") != t.npos )
1010 if( n_web1.size() == 0 )
1012 n_web1 = quo + r + quo;
1016 n_web2 = quo + r + quo;
1019 else if( t.find("icq") != t.npos )
1021 n_user1 = quo + r + quo;
1023 else if( t.find("notes") != t.npos )
1025 n_note = quo + r + quo;
1034 std::cout << n_web1 << sep << n_web2 << sep
1035 << n_byear << sep << n_bmonth << sep << n_bday << sep
1036 << n_user1 << sep << n_user2 << sep << n_user3 << sep << n_user4 << sep
1039 std::cout << std::endl;
1044 // ----------------------------------------------------------------------
1046 // ----------------------------------------------------------------------
1048 usage(int argc, char * argv[] )
1050 std::cerr << argv[0] << " -t (vcard|gnokii|csv|abook) -l (fr|en) bbdb.txt" << std::endl;
1051 std::cerr << "argc=" << argc << std::endl;
1057 // ----------------------------------------------------------------------
1059 // ----------------------------------------------------------------------
1061 main( int argc, char * argv[] )
1065 return usage(argc,argv);
1070 if( argc == 4 && !strcmp(argv[1],"-t") )
1072 if( !strcmp(argv[2],"vcard") )
1076 else if( !strcmp(argv[2],"csv") )
1080 else if( !strcmp(argv[2],"gnokii") )
1084 else if( !strcmp(argv[2],"abook") )
1090 return usage(argc,argv);
1093 else if( argc == 6 && !strcmp(argv[3],"-l") )
1096 if( strcmp(lg,"fr") && strcmp(argv[4],"en") )
1098 return usage(argc,argv);
1103 return usage(argc,argv);
1106 std::vector<std::string> v;
1110 fs.open( argv[argc-1], std::ios::in );
1111 if( ! fs.is_open() )
1113 std::cerr << "can't open " << argv[argc-1] << std::endl;
1119 fs.getline(data,1024);
1120 if( data[0] != ';' )
1122 v.push_back( data );
1131 std::for_each( v.begin(), v.end(), tognokii );
1134 std::for_each( v.begin(), v.end(), tovcard );
1137 std::for_each( v.begin(), v.end(), toabook );
1140 if( !strcmp( lg, "en" ))
1142 std::cout << "\"First Name\",\"Last Name\",\"Display Name\",\"Nickname Name\",\"E-mail\",\"Secondary E-mail\",\"Business Phone\",\"Home Phone\",\"Fax Phone\",\"Pager\",\"Mobile Phone\",\"Home Street 1\",\"Home Street 2\",\"Home City\",\"Home State\",\"Home Postal Code\",\"Home Country\",\"Business Street 1\",\"Business Street 2\",\"Business City\",\"Business State\",\"Business Postal Code\",\"Business Country\",\"Job Title\",\"Department\",\"Company\",\"Web Page 1\",\"Web Page 2\",\"Birth Year\",\"Birth Month\",\"Birth Day\",\"User Field 1\",\"User Field 2\",\"User Field 3\",\"User Field 4\",\"Notes\"" << std::endl;
1146 std::cout << "\"Prénom\",\"Nom\",\"Display Name\",\"Nickname Name\",\"E-mail\",\"Secondary E-mail\",\"Business Phone\",\"Téléphone\",\"Fax Phone\",\"Pager\",\"Mobile Phone\",\"Home Street 1\",\"Home Street 2\",\"Home City\",\"Home State\",\"Home Postal Code\",\"Home Country\",\"Business Street 1\",\"Business Street 2\",\"Business City\",\"Business State\",\"Business Postal Code\",\"Business Country\",\"Job Title\",\"Department\",\"Company\",\"Web Page 1\",\"Web Page 2\",\"Birth Year\",\"Birth Month\",\"Birth Day\",\"User Field 1\",\"User Field 2\",\"User Field 3\",\"User Field 4\",\"Notes\"" << std::endl;
1149 std::for_each( v.begin(), v.end(), tocsv );