From db05da322d7ef6bd94e097fb95af1ffead328b96 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rapha=C3=ABl=20Droz?= Date: Wed, 2 Jan 2013 14:56:45 +0100 Subject: [PATCH] * custom output format: fixes and enhancements - support for the {groups} placeholder - support for escaped characters (\n, \t, ...) - removed the leading empty line from the output - fix segfaults when an empty or a special format string was provided - referenced --outformatstr in --help - code cleanup: use of built-in ITEM_FIELDS and standard_fields[] to fetch standard fields numbering * vcard output: removed the leading empty line (which is mutt-specific) * colors: added the has_colors() ncurses check before actually initializing colors. * Changelog, RELEASE_NOTES, AUTHORS and THANKS files updated --- AUTHORS | 18 +++++++++++ ChangeLog | 3 ++ RELEASE_NOTES | 30 +++++++++++++++-- THANKS | 2 -- abook.c | 15 +++++++-- database.c | 2 +- filter.c | 90 ++++++++++++++++++++++++++++----------------------- ui.c | 2 +- 8 files changed, 113 insertions(+), 49 deletions(-) diff --git a/AUTHORS b/AUTHORS index 9570e77..e906315 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,3 +26,21 @@ Koenraad Heijlen - palmcsv export filter - fixes +Michael Krolikowski + - built-in vcard import filter + +Raphaël Droz + - custom output format + - reworked ldif input/output + - vcard import filter through libvformat + - fixes + +Thorsten Wißmann + - color support + - mouse support + +Fabio Zanini + - merge entries + - duplicated entries removal + - mutt "groups" + - fixes diff --git a/ChangeLog b/ChangeLog index 2dc0e1d..53d325e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,9 @@ git - extra-fields deletion bugfix (Jorrit Tijben) - additinal keybinding (Hagen Fuchs) - autotools update (Fabio Zanini) + - case-sensitive ldif fields parsing (Christian Brabandt) + - ldif standard input support (Raphaël Droz) + - ldif extensible field management rewritting (Raphaël Droz) 0.6.0 - configurable views (Cedric Duval) diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 92fcca6..32e5309 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -3,8 +3,34 @@ Please read this file carefully when upgrading abook. A more comprehensive list of changes can be found in the ChangeLog file. -- - -0.6.0pre2: +Git: + * support for mouse + * support for a colored UI + * added "groups" as a default field + * the UI now support merging selected entries [key M] + and removing duplicates [key U] + * a "custom" output filter allow the specification of an output + format using placeholders + * search-next is now bound to "/" too + * some output filters can now be used in the context + of --mutt-query. This is the case of "vcard" and "custom" + [ no --query option has been created and --mutt-query is fully + backward compatible ] + * ldif output filter has been fixed [output modified] in multiple + ways, does not force output to latin1 anymore and support input + from stdin. + * vcard input/output support: + An original input filter implementation was provided soon + after 0.6.0pre2. + In 2012, an optional build-time option to link against libvformat + was added for the very same task: parsing vcard. + - It depends on the --enable-vformat ./configure switch + - It's only used as an input filter, especially useful to + deal with multi-valued fields and encoded characters. + +0.6.0pre2 (2010-07-22): + * Added anniversary as a default field + * Display dates according to current locale * The four following configuration options have been deprecated and will no longer be accepted by abook: * emailpos diff --git a/THANKS b/THANKS index d53f9b6..5467984 100644 --- a/THANKS +++ b/THANKS @@ -21,7 +21,5 @@ Mariusz Balewski Marc Tardif Gerfried Fuchs Josef Schugt -Michael Krolikowski -Fabio Zanini See also AUTHORS diff --git a/abook.c b/abook.c index dd05b56..05ec429 100644 --- a/abook.c +++ b/abook.c @@ -415,7 +415,11 @@ parse_command_line(int argc, char **argv) } if(! selected_item_filter.func) selected_item_filter = select_output_item_filter("muttq"); - else if (! strcmp(outformat, "custom") && *custom_format) { + else if (! strcmp(outformat, "custom")) { + if(! *custom_format) { + fprintf(stderr, _("Invalid custom format string\n")); + exit(EXIT_FAILURE); + } parsed_custom_format = (char *)malloc(FORMAT_STRING_LEN * sizeof(char*)); custom_format_fields = (enum field_types *)malloc(FORMAT_STRING_MAX_FIELDS * sizeof(enum field_types *)); parse_custom_format(custom_format, parsed_custom_format, custom_format_fields); @@ -465,6 +469,8 @@ show_usage() puts (_(" (default: text)")); puts (_(" --outfile destination file")); puts (_(" (default: stdout)")); + puts (_(" --outformatstr format to use for \"custom\" --outformat")); + puts (_(" (default: \"{nick} ({name}): {mobile}\")")); puts (_(" --formats list available formats")); } @@ -496,7 +502,12 @@ mutt_query(char *str) printf("Not found\n"); quit_mutt_query(EXIT_FAILURE); } - putchar('\n'); + // mutt expects a leading line containing + // a message about the query. + // Others output filter supporting query (vcard, custom) + // don't needs this. + if(!strcmp(selected_item_filter.filtname, "muttq")) + putchar('\n'); while(i >= 0) { e_write_item(stdout, i, selected_item_filter.func); i = find_item(str, i + 1, search_fields); diff --git a/database.c b/database.c index 03d0abb..7dd4a9a 100644 --- a/database.c +++ b/database.c @@ -58,7 +58,7 @@ abook_field standard_fields[] = { {"url", N_("URL"), FIELD_STRING}, /* URL */ {"notes", N_("Notes"), FIELD_STRING}, /* NOTES */ {"anniversary", N_("Anniversary day"), FIELD_DATE}, /* ANNIVERSARY */ - {"groups", N_("Groups"), FIELD_LIST}, /* GROUPS */ + {"groups", N_("Groups"), FIELD_LIST}, /* GROUPS */ {0} /* ITEM_FIELDS */ }; diff --git a/filter.c b/filter.c index ecbcfd9..a22a0c7 100644 --- a/filter.c +++ b/filter.c @@ -2485,37 +2485,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 @@ -2529,17 +2507,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); @@ -2549,23 +2527,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 @@ -2598,7 +2606,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++; @@ -2612,7 +2620,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 { diff --git a/ui.c b/ui.c index 8fd38ae..158f2ed 100644 --- a/ui.c +++ b/ui.c @@ -139,7 +139,7 @@ ui_init_curses() ui_enable_mouse(TRUE); } keypad(stdscr, TRUE); - if(opt_get_bool(BOOL_USE_COLORS)) { + if(opt_get_bool(BOOL_USE_COLORS) && has_colors()) { start_color(); use_default_colors(); ui_init_color_pairs_user(); -- 2.39.2