+ return ret || interrupted;
+}
+
+static int
+tag_file (void *ctx, notmuch_database_t *notmuch, tag_op_flag_t flags,
+ FILE *input)
+{
+ char *line = NULL;
+ char *query_string = NULL;
+ size_t line_size = 0;
+ ssize_t line_len;
+ int ret = 0;
+ int warn = 0;
+ tag_op_list_t *tag_ops;
+
+ tag_ops = tag_op_list_create (ctx);
+ if (tag_ops == NULL) {
+ fprintf (stderr, "Out of memory.\n");
+ return 1;
+ }
+
+ while ((line_len = getline (&line, &line_size, input)) != -1 &&
+ ! interrupted) {
+
+ ret = parse_tag_line (ctx, line, TAG_FLAG_NONE,
+ &query_string, tag_ops);
+
+ if (ret > 0) {
+ if (ret != TAG_PARSE_SKIPPED)
+ /* remember there has been problematic lines */
+ warn = 1;
+ ret = 0;
+ continue;
+ }
+
+ if (ret < 0)
+ break;
+
+ ret = tag_query (ctx, notmuch, query_string, tag_ops, flags);
+ if (ret)
+ break;
+ }
+
+ if (line)
+ free (line);
+
+ return ret || warn;