[Patch v2 13/17] notmuch-restore: add support for input format 'batch-tag'
On Sat, 24 Nov 2012, david at tethera.net wrote: > From: David Bremner > > This is the same as the batch input for notmuch tag, except by default > it removes all tags before modifying a given message id and only "id:" > is supported. > --- > notmuch-restore.c | 199 > + > 1 file changed, 125 insertions(+), 74 deletions(-) > > diff --git a/notmuch-restore.c b/notmuch-restore.c > index f03dcac..22fcd2d 100644 > --- a/notmuch-restore.c > +++ b/notmuch-restore.c > @@ -19,18 +19,22 @@ > */ > > #include "notmuch-client.h" > +#include "dump-restore-private.h" > +#include "tag-util.h" > +#include "string-util.h" > + > +static volatile sig_atomic_t interrupted; > +static regex_t regex; > > static int > -tag_message (notmuch_database_t *notmuch, const char *message_id, > - char *file_tags, notmuch_bool_t remove_all, > - notmuch_bool_t synchronize_flags) > +tag_message (unused (void *ctx), > + notmuch_database_t *notmuch, > + const char *message_id, > + tag_op_list_t *tag_ops, > + tag_op_flag_t flags) > { > notmuch_status_t status; > -notmuch_tags_t *db_tags; > -char *db_tags_str; > notmuch_message_t *message = NULL; > -const char *tag; > -char *next; > int ret = 0; > > status = notmuch_database_find_message (notmuch, message_id, ); > @@ -44,55 +48,63 @@ tag_message (notmuch_database_t *notmuch, const char > *message_id, > > /* In order to detect missing messages, this check/optimization is > * intentionally done *after* first finding the message. */ > -if (! remove_all && (file_tags == NULL || *file_tags == '\0')) > - goto DONE; > - > -db_tags_str = NULL; > -for (db_tags = notmuch_message_get_tags (message); > - notmuch_tags_valid (db_tags); > - notmuch_tags_move_to_next (db_tags)) { > - tag = notmuch_tags_get (db_tags); > - > - if (db_tags_str) > - db_tags_str = talloc_asprintf_append (db_tags_str, " %s", tag); > - else > - db_tags_str = talloc_strdup (message, tag); > -} > +if ( (flags & TAG_FLAG_REMOVE_ALL) || (tag_op_list_size (tag_ops))) Extra space between ('s, and no need to wrap tag_op_list_size call in braces. > + tag_op_list_apply (message, tag_ops, flags); > > -if (((file_tags == NULL || *file_tags == '\0') && > - (db_tags_str == NULL || *db_tags_str == '\0')) || > - (file_tags && db_tags_str && strcmp (file_tags, db_tags_str) == 0)) This is a necessary optimization you're throwing away, but I'll get back to this after checking the last patch in the series. > - goto DONE; > +if (message) > + notmuch_message_destroy (message); message != NULL always, you can remove the if. > > -notmuch_message_freeze (message); > +return ret; > +} > > -if (remove_all) > - notmuch_message_remove_all_tags (message); > +static int > +parse_sup_line (void *ctx, char *line, > + char **query_str, tag_op_list_t *tag_ops) > +{ > > -next = file_tags; > -while (next) { > - tag = strsep (, " "); > - if (*tag == '\0') > - continue; > - status = notmuch_message_add_tag (message, tag); > - if (status) { > - fprintf (stderr, "Error applying tag %s to message %s:\n", > - tag, message_id); > - fprintf (stderr, "%s\n", notmuch_status_to_string (status)); > - ret = 1; > - } > +regmatch_t match[3]; > +char *file_tags; > +int rerr; > + > +tag_op_list_reset (tag_ops); > + > +chomp_newline (line); > + > +/* Silently ignore blank lines */ > +if (line[0] == '\0') { > + return 1; > +} > + > +rerr = xregexec (, line, 3, match, 0); > +if (rerr == REG_NOMATCH) { > + fprintf (stderr, "Warning: Ignoring invalid input line: %s\n", > + line); > + return 1; > } > > -notmuch_message_thaw (message); > +*query_str = talloc_strndup (ctx, line + match[1].rm_so, > + match[1].rm_eo - match[1].rm_so); > +file_tags = talloc_strndup (ctx, line + match[2].rm_so, > + match[2].rm_eo - match[2].rm_so); > > -if (synchronize_flags) > - notmuch_message_tags_to_maildir_flags (message); > +char *tok = file_tags; > +size_t tok_len = 0; > > - DONE: > -if (message) > - notmuch_message_destroy (message); > +tag_op_list_reset (tag_ops); > + > +while ((tok = strtok_len (tok + tok_len, " ", _len)) != NULL) { > + > + if (*(tok + tok_len) != '\0') { > + *(tok + tok_len) = '\0'; > + tok_len++; > + } > + > + if (tag_op_list_append (ctx, tag_ops, tok, FALSE)) > + return -1; > +} > + > +return 0; > > -return ret; > } > > int > @@ -100,16 +112,19 @@ notmuch_restore_command (unused (void *ctx), int argc, > char *argv[]) > { > notmuch_config_t *config; > notmuch_database_t
Re: [Patch v2 13/17] notmuch-restore: add support for input format 'batch-tag'
On Sat, 24 Nov 2012, da...@tethera.net wrote: From: David Bremner brem...@debian.org This is the same as the batch input for notmuch tag, except by default it removes all tags before modifying a given message id and only id: is supported. --- notmuch-restore.c | 199 + 1 file changed, 125 insertions(+), 74 deletions(-) diff --git a/notmuch-restore.c b/notmuch-restore.c index f03dcac..22fcd2d 100644 --- a/notmuch-restore.c +++ b/notmuch-restore.c @@ -19,18 +19,22 @@ */ #include notmuch-client.h +#include dump-restore-private.h +#include tag-util.h +#include string-util.h + +static volatile sig_atomic_t interrupted; +static regex_t regex; static int -tag_message (notmuch_database_t *notmuch, const char *message_id, - char *file_tags, notmuch_bool_t remove_all, - notmuch_bool_t synchronize_flags) +tag_message (unused (void *ctx), + notmuch_database_t *notmuch, + const char *message_id, + tag_op_list_t *tag_ops, + tag_op_flag_t flags) { notmuch_status_t status; -notmuch_tags_t *db_tags; -char *db_tags_str; notmuch_message_t *message = NULL; -const char *tag; -char *next; int ret = 0; status = notmuch_database_find_message (notmuch, message_id, message); @@ -44,55 +48,63 @@ tag_message (notmuch_database_t *notmuch, const char *message_id, /* In order to detect missing messages, this check/optimization is * intentionally done *after* first finding the message. */ -if (! remove_all (file_tags == NULL || *file_tags == '\0')) - goto DONE; - -db_tags_str = NULL; -for (db_tags = notmuch_message_get_tags (message); - notmuch_tags_valid (db_tags); - notmuch_tags_move_to_next (db_tags)) { - tag = notmuch_tags_get (db_tags); - - if (db_tags_str) - db_tags_str = talloc_asprintf_append (db_tags_str, %s, tag); - else - db_tags_str = talloc_strdup (message, tag); -} +if ( (flags TAG_FLAG_REMOVE_ALL) || (tag_op_list_size (tag_ops))) Extra space between ('s, and no need to wrap tag_op_list_size call in braces. + tag_op_list_apply (message, tag_ops, flags); -if (((file_tags == NULL || *file_tags == '\0') - (db_tags_str == NULL || *db_tags_str == '\0')) || - (file_tags db_tags_str strcmp (file_tags, db_tags_str) == 0)) This is a necessary optimization you're throwing away, but I'll get back to this after checking the last patch in the series. - goto DONE; +if (message) + notmuch_message_destroy (message); message != NULL always, you can remove the if. -notmuch_message_freeze (message); +return ret; +} -if (remove_all) - notmuch_message_remove_all_tags (message); +static int +parse_sup_line (void *ctx, char *line, + char **query_str, tag_op_list_t *tag_ops) +{ -next = file_tags; -while (next) { - tag = strsep (next, ); - if (*tag == '\0') - continue; - status = notmuch_message_add_tag (message, tag); - if (status) { - fprintf (stderr, Error applying tag %s to message %s:\n, - tag, message_id); - fprintf (stderr, %s\n, notmuch_status_to_string (status)); - ret = 1; - } +regmatch_t match[3]; +char *file_tags; +int rerr; + +tag_op_list_reset (tag_ops); + +chomp_newline (line); + +/* Silently ignore blank lines */ +if (line[0] == '\0') { + return 1; +} + +rerr = xregexec (regex, line, 3, match, 0); +if (rerr == REG_NOMATCH) { + fprintf (stderr, Warning: Ignoring invalid input line: %s\n, + line); + return 1; } -notmuch_message_thaw (message); +*query_str = talloc_strndup (ctx, line + match[1].rm_so, + match[1].rm_eo - match[1].rm_so); +file_tags = talloc_strndup (ctx, line + match[2].rm_so, + match[2].rm_eo - match[2].rm_so); -if (synchronize_flags) - notmuch_message_tags_to_maildir_flags (message); +char *tok = file_tags; +size_t tok_len = 0; - DONE: -if (message) - notmuch_message_destroy (message); +tag_op_list_reset (tag_ops); + +while ((tok = strtok_len (tok + tok_len, , tok_len)) != NULL) { + + if (*(tok + tok_len) != '\0') { + *(tok + tok_len) = '\0'; + tok_len++; + } + + if (tag_op_list_append (ctx, tag_ops, tok, FALSE)) + return -1; +} + +return 0; -return ret; } int @@ -100,16 +112,19 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; -notmuch_bool_t synchronize_flags; notmuch_bool_t accumulate = FALSE; +tag_op_flag_t flags = 0; +tag_op_list_t *tag_ops;
[Patch v2 13/17] notmuch-restore: add support for input format 'batch-tag'
From: David BremnerThis is the same as the batch input for notmuch tag, except by default it removes all tags before modifying a given message id and only "id:" is supported. --- notmuch-restore.c | 199 + 1 file changed, 125 insertions(+), 74 deletions(-) diff --git a/notmuch-restore.c b/notmuch-restore.c index f03dcac..22fcd2d 100644 --- a/notmuch-restore.c +++ b/notmuch-restore.c @@ -19,18 +19,22 @@ */ #include "notmuch-client.h" +#include "dump-restore-private.h" +#include "tag-util.h" +#include "string-util.h" + +static volatile sig_atomic_t interrupted; +static regex_t regex; static int -tag_message (notmuch_database_t *notmuch, const char *message_id, -char *file_tags, notmuch_bool_t remove_all, -notmuch_bool_t synchronize_flags) +tag_message (unused (void *ctx), +notmuch_database_t *notmuch, +const char *message_id, +tag_op_list_t *tag_ops, +tag_op_flag_t flags) { notmuch_status_t status; -notmuch_tags_t *db_tags; -char *db_tags_str; notmuch_message_t *message = NULL; -const char *tag; -char *next; int ret = 0; status = notmuch_database_find_message (notmuch, message_id, ); @@ -44,55 +48,63 @@ tag_message (notmuch_database_t *notmuch, const char *message_id, /* In order to detect missing messages, this check/optimization is * intentionally done *after* first finding the message. */ -if (! remove_all && (file_tags == NULL || *file_tags == '\0')) - goto DONE; - -db_tags_str = NULL; -for (db_tags = notmuch_message_get_tags (message); -notmuch_tags_valid (db_tags); -notmuch_tags_move_to_next (db_tags)) { - tag = notmuch_tags_get (db_tags); - - if (db_tags_str) - db_tags_str = talloc_asprintf_append (db_tags_str, " %s", tag); - else - db_tags_str = talloc_strdup (message, tag); -} +if ( (flags & TAG_FLAG_REMOVE_ALL) || (tag_op_list_size (tag_ops))) + tag_op_list_apply (message, tag_ops, flags); -if (((file_tags == NULL || *file_tags == '\0') && -(db_tags_str == NULL || *db_tags_str == '\0')) || - (file_tags && db_tags_str && strcmp (file_tags, db_tags_str) == 0)) - goto DONE; +if (message) + notmuch_message_destroy (message); -notmuch_message_freeze (message); +return ret; +} -if (remove_all) - notmuch_message_remove_all_tags (message); +static int +parse_sup_line (void *ctx, char *line, + char **query_str, tag_op_list_t *tag_ops) +{ -next = file_tags; -while (next) { - tag = strsep (, " "); - if (*tag == '\0') - continue; - status = notmuch_message_add_tag (message, tag); - if (status) { - fprintf (stderr, "Error applying tag %s to message %s:\n", -tag, message_id); - fprintf (stderr, "%s\n", notmuch_status_to_string (status)); - ret = 1; - } +regmatch_t match[3]; +char *file_tags; +int rerr; + +tag_op_list_reset (tag_ops); + +chomp_newline (line); + +/* Silently ignore blank lines */ +if (line[0] == '\0') { + return 1; +} + +rerr = xregexec (, line, 3, match, 0); +if (rerr == REG_NOMATCH) { + fprintf (stderr, "Warning: Ignoring invalid input line: %s\n", +line); + return 1; } -notmuch_message_thaw (message); +*query_str = talloc_strndup (ctx, line + match[1].rm_so, +match[1].rm_eo - match[1].rm_so); +file_tags = talloc_strndup (ctx, line + match[2].rm_so, + match[2].rm_eo - match[2].rm_so); -if (synchronize_flags) - notmuch_message_tags_to_maildir_flags (message); +char *tok = file_tags; +size_t tok_len = 0; - DONE: -if (message) - notmuch_message_destroy (message); +tag_op_list_reset (tag_ops); + +while ((tok = strtok_len (tok + tok_len, " ", _len)) != NULL) { + + if (*(tok + tok_len) != '\0') { + *(tok + tok_len) = '\0'; + tok_len++; + } + + if (tag_op_list_append (ctx, tag_ops, tok, FALSE)) + return -1; +} + +return 0; -return ret; } int @@ -100,16 +112,19 @@ notmuch_restore_command (unused (void *ctx), int argc, char *argv[]) { notmuch_config_t *config; notmuch_database_t *notmuch; -notmuch_bool_t synchronize_flags; notmuch_bool_t accumulate = FALSE; +tag_op_flag_t flags = 0; +tag_op_list_t *tag_ops; + char *input_file_name = NULL; FILE *input = stdin; char *line = NULL; size_t line_size; ssize_t line_len; -regex_t regex; -int rerr; + +int ret = 0; int opt_index; +int input_format = DUMP_FORMAT_AUTO; config = notmuch_config_open (ctx, NULL, NULL); if (config == NULL) @@ -119,9 +134,15 @@