Re: [PATCH 1/3] cli: add support for --no- prefixed boolean and keyword flag arguments

2017-10-14 Thread William Casarin

Tested ACK 1-3 + id:20171014201836.4486-1-j...@nikula.org
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 1/3] cli: add support for --no- prefixed boolean and keyword flag arguments

2017-10-14 Thread William Casarin
Jani Nikula  writes:

> *blush* I screwed those enums up. Here's a patch that takes care of both
> issues id:20171014201836.4486-1-j...@nikula.org. It's independent of
> this series.

Works, thanks.

-- 
https://jb55.com
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 1/3] cli: add support for --no- prefixed boolean and keyword flag arguments

2017-10-14 Thread Jani Nikula
On Sat, 14 Oct 2017, William Casarin  wrote:
> Hey Jani,
>
> Patches look good so far, concept ack for sure.
>
>
> Jani Nikula  writes:
>
>> For example, you can use --no-exclude instead of --exclude=false in
>> notmuch show. If we had keyword flag arguments with some flags
>> defaulting to on, say --include=tags in notmuch dump/restore, this
>> would allow --no-include=tags to switch that off while not affecting
>> other flags.
>
> I've been testing it a bit, I can't seem to make this work in this example:
>
> ./notmuch count --no-exclude
>
> After some brief investigation it might be because count is using
> EXCLUDE_true(1) and EXCLUDE_false(0) which are not equal to
> NOTMUCH_EXCLUDE_TRUE(1) and NOTMUCH_EXCLUDE_FALSE(2), but I'm not sure.

*blush* I screwed those enums up. Here's a patch that takes care of both
issues id:20171014201836.4486-1-j...@nikula.org. It's independent of
this series.

BR,
Jani.


___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH] cli: make notmuch count --exclude a boolean argument

2017-10-14 Thread Jani Nikula
Commit 0f314c0c99be ("cli: convert notmuch_bool_t to stdbool")
over-eagerly converted EXCLUDE_TRUE and EXCLUDE_FALSE to EXCLUDE_true
and EXCLUDE_false in notmuch-count.c. We could just fix the case back,
but convert the option to an actual boolean argument instead.

We've used a keyword argument rather than a boolean argument for
notmuch count --exclude for five years, since commit 785c1e497f05
("cli: move count to the new --exclude=(true|false|flag) naming
scheme."), "to allow future options to be added more easily". I think
we can conclude future options aren't coming any time soon.
---
 notmuch-count.c | 15 +++
 1 file changed, 3 insertions(+), 12 deletions(-)

diff --git a/notmuch-count.c b/notmuch-count.c
index 1ae7d5146d92..ca05c9793b70 100644
--- a/notmuch-count.c
+++ b/notmuch-count.c
@@ -27,12 +27,6 @@ enum {
 OUTPUT_FILES,
 };
 
-/* The following is to allow future options to be added more easily */
-enum {
-EXCLUDE_true,
-EXCLUDE_false,
-};
-
 /* Return the number of files matching the query, or -1 for an error */
 static int
 count_files (notmuch_query_t *query)
@@ -160,7 +154,7 @@ notmuch_count_command (notmuch_config_t *config, int argc, 
char *argv[])
 char *query_str;
 int opt_index;
 int output = OUTPUT_MESSAGES;
-int exclude = EXCLUDE_true;
+bool exclude = true;
 const char **search_exclude_tags = NULL;
 size_t search_exclude_tags_length = 0;
 bool batch = false;
@@ -175,10 +169,7 @@ notmuch_count_command (notmuch_config_t *config, int argc, 
char *argv[])
  { "messages", OUTPUT_MESSAGES },
  { "files", OUTPUT_FILES },
  { 0, 0 } } },
-   { .opt_keyword = , .name = "exclude", .keywords =
- (notmuch_keyword_t []){ { "true", EXCLUDE_true },
- { "false", EXCLUDE_false },
- { 0, 0 } } },
+   { .opt_bool = , .name = "exclude" },
{ .opt_bool = _lastmod, .name = "lastmod" },
{ .opt_bool = , .name = "batch" },
{ .opt_string = _file_name, .name = "input" },
@@ -221,7 +212,7 @@ notmuch_count_command (notmuch_config_t *config, int argc, 
char *argv[])
return EXIT_FAILURE;
 }
 
-if (exclude == EXCLUDE_true) {
+if (exclude) {
search_exclude_tags = notmuch_config_get_search_exclude_tags
(config, _exclude_tags_length);
 }
-- 
2.11.0

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [bug] [emacs] notmuch-show: names not shown on some mailing lists

2017-10-14 Thread William Casarin
Nevermind, the issue seems to go away on master

Sorry for the noise...
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 1/3] cli: add support for --no- prefixed boolean and keyword flag arguments

2017-10-14 Thread William Casarin

Hey Jani,

Patches look good so far, concept ack for sure.


Jani Nikula  writes:

> For example, you can use --no-exclude instead of --exclude=false in
> notmuch show. If we had keyword flag arguments with some flags
> defaulting to on, say --include=tags in notmuch dump/restore, this
> would allow --no-include=tags to switch that off while not affecting
> other flags.

I've been testing it a bit, I can't seem to make this work in this example:

./notmuch count --no-exclude

After some brief investigation it might be because count is using
EXCLUDE_true(1) and EXCLUDE_false(0) which are not equal to
NOTMUCH_EXCLUDE_TRUE(1) and NOTMUCH_EXCLUDE_FALSE(2), but I'm not sure.

Cheers,
William

-- 
https://jb55.com
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [bug] [emacs] notmuch-show: names not shown on some mailing lists

2017-10-14 Thread William Casarin
William Casarin  writes:

> Jani Nikula  writes:
>
>> The information comes from the cli. Can you reproduce this using some
>> notmuch show --format=sexp --body=false query, perhaps on just one of
>> the messages?
>
> I get this:
>
>   :From "Person via Mailing list\011"

If I wanted to fix this, would I implement it as a wash function?

Thanks,


-- 
https://jb55.com
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [bug] [emacs] notmuch-show: names not shown on some mailing lists

2017-10-14 Thread William Casarin
Jani Nikula  writes:

> The information comes from the cli. Can you reproduce this using some
> notmuch show --format=sexp --body=false query, perhaps on just one of
> the messages?

I get this:

  :From "Person via Mailing list\011"


-- 
https://jb55.com
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v3 11/15] config: indexing defaults will be stored in the database.

2017-10-14 Thread David Bremner
Daniel Kahn Gillmor  writes:


>  static int
>  _print_db_config(notmuch_config_t *config, const char *name)
> @@ -859,6 +860,8 @@ notmuch_config_command_get (notmuch_config_t *config, 
> char *item)
>   notmuch_built_with (item + strlen (BUILT_WITH_PREFIX)) ? "true" 
> : "false");
>  } else if (STRNCMP_LITERAL (item, QUERY_PREFIX) == 0) {
>   return _print_db_config (config, item);
> +} else if (STRNCMP_LITERAL (item, INDEX_PREFIX) == 0) {
> + return _print_db_config (config, item);
>  } else {
>   char **value;

I wonder if we should sanity check the value of 'item' more here. With
'query.', it makes sense to get or set anything, since it's just the
name of a stored query. With 'index.', presumably only certain
parameters make sense. As a motivating example, consider someone who
sets

$ notmuch config index.try_decrypt true

then changes their mind

$ notmuch config index.try-decrypt false

They _think_ they are safe, but notmuch is silently going to continue
decrypting their mail
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v3 09/15] gmime-extra: drop compat layer for g_mime_multipart_encrypted_decrypt

2017-10-14 Thread David Bremner
Daniel Kahn Gillmor  writes:

> In practice, we're going to see this function invoked differently
> depending on which gmime we build against.  The compatibility layer
> forces our code into the lowest-common-denominator -- unable to make
> use of new features even when built against a newer version.
>
> Dropping the compatibility layer paves the way for clearer use of
> features from GMime 3.0 in future commits.

pushed patches 7 and 9.

d
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/3] cli: use the negating boolean support for new and insert --no-hooks

2017-10-14 Thread Jani Nikula
This lets us use the positive hooks variable in code, increasing
clarity.
---
 notmuch-insert.c | 6 +++---
 notmuch-new.c| 8 
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/notmuch-insert.c b/notmuch-insert.c
index 32be74193472..6878313e188f 100644
--- a/notmuch-insert.c
+++ b/notmuch-insert.c
@@ -455,7 +455,7 @@ notmuch_insert_command (notmuch_config_t *config, int argc, 
char *argv[])
 const char *folder = "";
 bool create_folder = false;
 bool keep = false;
-bool no_hooks = false;
+bool hooks = true;
 bool synchronize_flags;
 char *maildir;
 char *newpath;
@@ -466,7 +466,7 @@ notmuch_insert_command (notmuch_config_t *config, int argc, 
char *argv[])
{ .opt_string = , .name = "folder" },
{ .opt_bool = _folder, .name = "create-folder" },
{ .opt_bool = , .name = "keep" },
-   { .opt_bool =  _hooks, .name = "no-hooks" },
+   { .opt_bool = , .name = "hooks" },
{ .opt_inherit = notmuch_shared_options },
{ }
 };
@@ -573,7 +573,7 @@ notmuch_insert_command (notmuch_config_t *config, int argc, 
char *argv[])
}
 }
 
-if (! no_hooks && status == NOTMUCH_STATUS_SUCCESS) {
+if (hooks && status == NOTMUCH_STATUS_SUCCESS) {
/* Ignore hook failures. */
notmuch_run_hook (db_path, "post-insert");
 }
diff --git a/notmuch-new.c b/notmuch-new.c
index 0f50457eb894..a6ca484101ce 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -954,7 +954,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, 
char *argv[])
 int opt_index;
 unsigned int i;
 bool timer_is_active = false;
-bool no_hooks = false;
+bool hooks = true;
 bool quiet = false, verbose = false;
 notmuch_status_t status;
 
@@ -962,7 +962,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, 
char *argv[])
{ .opt_bool = , .name = "quiet" },
{ .opt_bool = , .name = "verbose" },
{ .opt_bool = _files_state.debug, .name = "debug" },
-   { .opt_bool = _hooks, .name = "no-hooks" },
+   { .opt_bool = , .name = "hooks" },
{ .opt_inherit = notmuch_shared_options },
{ }
 };
@@ -995,7 +995,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, 
char *argv[])
}
 }
 
-if (!no_hooks) {
+if (hooks) {
ret = notmuch_run_hook (db_path, "pre-new");
if (ret)
return EXIT_FAILURE;
@@ -1160,7 +1160,7 @@ notmuch_new_command (notmuch_config_t *config, int argc, 
char *argv[])
 
 notmuch_database_destroy (notmuch);
 
-if (!no_hooks && !ret && !interrupted)
+if (hooks && !ret && !interrupted)
ret = notmuch_run_hook (db_path, "post-new");
 
 if (ret || interrupted)
-- 
2.11.0

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 2/2] test: test regexp based new.ignore

2017-10-14 Thread Jani Nikula
Just some basics.
---
 test/T050-new.sh | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/test/T050-new.sh b/test/T050-new.sh
index 272ed417aa2e..ee9ce08c8e86 100755
--- a/test/T050-new.sh
+++ b/test/T050-new.sh
@@ -259,6 +259,28 @@ ln -s i_do_not_exist "${MAIL_DIR}"/broken_link
 output=$(NOTMUCH_NEW 2>&1)
 test_expect_equal "$output" "No new mail."
 
+test_begin_subtest "Ignore files and directories specified in new.ignore 
(regexp)"
+notmuch config set new.ignore ".git" "/^bro.*ink\$/" "/ignored.*file/"
+output=$(NOTMUCH_NEW --debug 2>&1 | sort)
+test_expect_equal "$output" \
+"(D) add_files, pass 1: explicitly ignoring ${MAIL_DIR}/.git
+(D) add_files, pass 1: explicitly ignoring ${MAIL_DIR}/.ignored_hidden_file
+(D) add_files, pass 1: explicitly ignoring ${MAIL_DIR}/broken_link
+(D) add_files, pass 1: explicitly ignoring ${MAIL_DIR}/ignored_file
+(D) add_files, pass 1: explicitly ignoring ${MAIL_DIR}/one/ignored_file
+(D) add_files, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/ignored_file
+(D) add_files, pass 1: explicitly ignoring ${MAIL_DIR}/one/two/three/.git
+(D) add_files, pass 1: explicitly ignoring 
${MAIL_DIR}/one/two/three/ignored_file
+(D) add_files, pass 2: explicitly ignoring ${MAIL_DIR}/.git
+(D) add_files, pass 2: explicitly ignoring ${MAIL_DIR}/.ignored_hidden_file
+(D) add_files, pass 2: explicitly ignoring ${MAIL_DIR}/broken_link
+(D) add_files, pass 2: explicitly ignoring ${MAIL_DIR}/ignored_file
+(D) add_files, pass 2: explicitly ignoring ${MAIL_DIR}/one/ignored_file
+(D) add_files, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/ignored_file
+(D) add_files, pass 2: explicitly ignoring ${MAIL_DIR}/one/two/three/.git
+(D) add_files, pass 2: explicitly ignoring 
${MAIL_DIR}/one/two/three/ignored_file
+No new mail."
+
 test_begin_subtest "Quiet: No new mail."
 output=$(NOTMUCH_NEW --quiet)
 test_expect_equal "$output" ""
-- 
2.11.0

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 3/3] test: expand argument parsing sanity checks

2017-10-14 Thread Jani Nikula
Test the various boolean formats and --no- prefixed boolean and
keyword flag arguments.
---
 test/T410-argument-parsing.sh | 28 
 1 file changed, 28 insertions(+)

diff --git a/test/T410-argument-parsing.sh b/test/T410-argument-parsing.sh
index 4a2b25c6486d..243d0241b9b6 100755
--- a/test/T410-argument-parsing.sh
+++ b/test/T410-argument-parsing.sh
@@ -37,4 +37,32 @@ positional arg 1 false
 EOF
 test_expect_equal_file EXPECTED OUTPUT
 
+test_begin_subtest "--boolean=true"
+$TEST_DIRECTORY/arg-test --boolean=true > OUTPUT
+cat < EXPECTED
+boolean 1
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "--boolean=false"
+$TEST_DIRECTORY/arg-test --boolean=false > OUTPUT
+cat < EXPECTED
+boolean 0
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "--no-boolean"
+$TEST_DIRECTORY/arg-test --no-boolean > OUTPUT
+cat < EXPECTED
+boolean 0
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
+test_begin_subtest "--no-flag"
+$TEST_DIRECTORY/arg-test --flag=one --flag=three --no-flag=three > OUTPUT
+cat < EXPECTED
+flags 1
+EOF
+test_expect_equal_file EXPECTED OUTPUT
+
 test_done
-- 
2.11.0

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


[PATCH 1/2] cli/new: support // in new.ignore

2017-10-14 Thread Jani Nikula
Add support for using // style regular expressions in
new.ignore, mixed with the old style verbatim file and directory
basenames. The regex is matched against the relative path from the
database path.
---
 doc/man1/notmuch-config.rst |  21 +--
 notmuch-new.c   | 134 
 2 files changed, 140 insertions(+), 15 deletions(-)

diff --git a/doc/man1/notmuch-config.rst b/doc/man1/notmuch-config.rst
index 6a51e64f1517..0af86f9beee4 100644
--- a/doc/man1/notmuch-config.rst
+++ b/doc/man1/notmuch-config.rst
@@ -75,11 +75,22 @@ The available configuration items are described below.
 Default: ``unread;inbox``.
 
 **new.ignore**
-A list of file and directory names, without path, that will not
-be searched for messages by **notmuch new**. All the files and
-directories matching any of the names specified here will be
-ignored, regardless of the location in the mail store directory
-hierarchy.
+A list to specify files and directories that will not be
+searched for messages by **notmuch new**. Each entry in the
+list is either:
+
+  A file or a directory name, without path, that will be
+  ignored, regardless of the location in the mail store
+  directory hierarchy.
+
+Or:
+
+  A regular expression delimited with // that will be matched
+  against the path of the file or directory relative to the
+  database path. Matching files and directories will be
+  ignored. The beginning and end of string must be explictly
+  anchored. For example, /.*/foo$/ would match "bar/foo" and
+  "bar/baz/foo", but not "foo" or "bar/foobar".
 
 Default: empty list.
 
diff --git a/notmuch-new.c b/notmuch-new.c
index 0f50457eb894..5a262e419b44 100644
--- a/notmuch-new.c
+++ b/notmuch-new.c
@@ -42,13 +42,17 @@ enum verbosity {
 };
 
 typedef struct {
+const char *db_path;
+
 int output_is_a_tty;
 enum verbosity verbosity;
 bool debug;
 const char **new_tags;
 size_t new_tags_length;
-const char **new_ignore;
-size_t new_ignore_length;
+const char **ignore_verbatim;
+size_t ignore_verbatim_length;
+regex_t *ignore_regex;
+size_t ignore_regex_length;
 
 int total_files;
 int processed_files;
@@ -240,18 +244,125 @@ _special_directory (const char *entry)
 return strcmp (entry, ".") == 0 || strcmp (entry, "..") == 0;
 }
 
+static bool
+_setup_ignore (notmuch_config_t *config, add_files_state_t *state)
+{
+const char **ignore_list, **ignore;
+int nregex = 0, nverbatim = 0;
+const char **verbatim = NULL;
+regex_t *regex = NULL;
+
+ignore_list = notmuch_config_get_new_ignore (config, NULL);
+if (! ignore_list)
+   return true;
+
+for (ignore = ignore_list; *ignore; ignore++) {
+   const char *s = *ignore;
+   size_t len = strlen (s);
+
+   if (len == 0) {
+   fprintf (stderr, "Error: Empty string in new.ignore list\n");
+   return false;
+   }
+
+   if (s[0] == '/') {
+   regex_t *preg;
+   char *r;
+   int rerr;
+
+   if (len < 3 || s[len - 1] != '/') {
+   fprintf (stderr, "Error: Malformed pattern '%s' in 
new.ignore\n",
+s);
+   return false;
+   }
+
+   r = talloc_strndup (config, s + 1, len - 2);
+   regex = talloc_realloc (config, regex, regex_t, nregex + 1);
+   preg = [nregex];
+
+   rerr = regcomp (preg, r, REG_EXTENDED | REG_NOSUB);
+   if (rerr) {
+   size_t error_size = regerror (rerr, preg, NULL, 0);
+   char *error = talloc_size (r, error_size);
+
+   regerror (rerr, preg, error, error_size);
+
+   fprintf (stderr, "Error: Invalid regex '%s' in new.ignore: 
%s\n",
+r, error);
+   return false;
+   }
+   nregex++;
+
+   talloc_free (r);
+   } else {
+   verbatim = talloc_realloc (config, verbatim, const char *,
+  nverbatim + 1);
+   verbatim[nverbatim++] = s;
+   }
+}
+
+state->ignore_regex = regex;
+state->ignore_regex_length = nregex;
+state->ignore_verbatim = verbatim;
+state->ignore_verbatim_length = nverbatim;
+
+return true;
+}
+
+static char *
+_get_relative_path (const char *db_path, const char *dirpath, const char 
*entry)
+{
+size_t db_path_len = strlen (db_path);
+
+/* paranoia? */
+if (strncmp (dirpath, db_path, db_path_len) != 0) {
+   fprintf (stderr, "Warning: '%s' is not a subdirectory of '%s'\n",
+dirpath, db_path);
+   return NULL;
+}
+
+dirpath += db_path_len;
+while (*dirpath == '/')
+   dirpath++;
+
+if (*dirpath)
+   return talloc_asprintf (NULL, "%s/%s", dirpath, entry);
+else
+   return 

[PATCH 1/3] cli: add support for --no- prefixed boolean and keyword flag arguments

2017-10-14 Thread Jani Nikula
Add transparent support for negating boolean and keyword flag
arguments using --no-argument style on the command line. That is, if
the option description contains a boolean or a keyword flag argument
named "argument", --no-argument will match and negate it.

For boolean arguments this obviously means the logical NOT. For
keyword flag arguments this means bitwise AND of the bitwise NOT,
i.e. masking out the specified bits instead of OR'ing them in.

For example, you can use --no-exclude instead of --exclude=false in
notmuch show. If we had keyword flag arguments with some flags
defaulting to on, say --include=tags in notmuch dump/restore, this
would allow --no-include=tags to switch that off while not affecting
other flags.

As a curiosity, you should be able to warp your brain using
--no-exclude=true meaning false and --no-exclude=false meaning true if
you wish.

Specifying both "argument" and "no-argument" style arguments in the
same option description should be avoided. In this case, --no-argument
would match whichever is specified first, and --argument would only
match "argument".
---
 command-line-arguments.c | 48 +---
 1 file changed, 37 insertions(+), 11 deletions(-)

diff --git a/command-line-arguments.c b/command-line-arguments.c
index 1ff5aae578c6..69ee1cb07f47 100644
--- a/command-line-arguments.c
+++ b/command-line-arguments.c
@@ -11,8 +11,9 @@
 */
 
 static bool
-_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next, const 
char *arg_str) {
-
+_process_keyword_arg (const notmuch_opt_desc_t *arg_desc, char next,
+ const char *arg_str, bool negate)
+{
 const notmuch_keyword_t *keywords;
 
 if (next == '\0') {
@@ -24,7 +25,9 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, 
char next, const char
if (strcmp (arg_str, keywords->name) != 0)
continue;
 
-   if (arg_desc->opt_flags)
+   if (arg_desc->opt_flags && negate)
+   *arg_desc->opt_flags &= ~keywords->value;
+   else if (arg_desc->opt_flags)
*arg_desc->opt_flags |= keywords->value;
else
*arg_desc->opt_keyword = keywords->value;
@@ -39,7 +42,9 @@ _process_keyword_arg (const notmuch_opt_desc_t *arg_desc, 
char next, const char
 }
 
 static bool
-_process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next, const 
char *arg_str) {
+_process_boolean_arg (const notmuch_opt_desc_t *arg_desc, char next,
+ const char *arg_str, bool negate)
+{
 bool value;
 
 if (next == '\0' || strcmp (arg_str, "true") == 0) {
@@ -51,7 +56,7 @@ _process_boolean_arg (const notmuch_opt_desc_t *arg_desc, 
char next, const char
return false;
 }
 
-*arg_desc->opt_bool = value;
+*arg_desc->opt_bool = negate ? !value : value;
 
 return true;
 }
@@ -139,6 +144,8 @@ parse_position_arg (const char *arg_str, int pos_arg_index,
 return false;
 }
 
+#define NEGATIVE_PREFIX "no-"
+
 /*
  * Search for a non-positional (i.e. starting with --) argument matching arg,
  * parse a possible value, and assign to *output_var
@@ -155,6 +162,14 @@ parse_option (int argc, char **argv, const 
notmuch_opt_desc_t *options, int opt_
 assert(options);
 
 const char *arg = _arg + 2; /* _arg starts with -- */
+const char *negative_arg = NULL;
+
+/* See if this is a --no-argument */
+if (strlen (arg) > strlen (NEGATIVE_PREFIX) &&
+   strncmp (arg, NEGATIVE_PREFIX, strlen (NEGATIVE_PREFIX)) == 0) {
+   negative_arg = arg + strlen (NEGATIVE_PREFIX);
+}
+
 const notmuch_opt_desc_t *try;
 
 const char *next_arg = NULL;
@@ -171,11 +186,22 @@ parse_option (int argc, char **argv, const 
notmuch_opt_desc_t *options, int opt_
if (! try->name)
continue;
 
-   if (strncmp (arg, try->name, strlen (try->name)) != 0)
+   char next;
+   const char *value;
+   bool negate = false;
+
+   if (strncmp (arg, try->name, strlen (try->name)) == 0) {
+   next = arg[strlen (try->name)];
+   value = arg + strlen (try->name) + 1;
+   } else if (negative_arg && (try->opt_bool || try->opt_flags) &&
+  strncmp (negative_arg, try->name, strlen (try->name)) == 0) {
+   next = negative_arg[strlen (try->name)];
+   value = negative_arg + strlen (try->name) + 1;
+   /* The argument part of --no-argument matches, negate the result. */
+   negate = true;
+   } else {
continue;
-
-   char next = arg[strlen (try->name)];
-   const char *value = arg + strlen(try->name) + 1;
+   }
 
/*
 * If we have not reached the end of the argument (i.e. the
@@ -194,9 +220,9 @@ parse_option (int argc, char **argv, const 
notmuch_opt_desc_t *options, int opt_
 
bool opt_status = false;
if (try->opt_keyword || try->opt_flags)
-   opt_status = _process_keyword_arg (try, next, value);
+   opt_status = 

[PATCH] cli: allow empty strings for notmuch insert --folder argument

2017-10-14 Thread Jani Nikula
Now that it's easy to add argument specific modifiers in opt
descriptions, add a new .allow_empty field to allow empty strings for
individual string arguments while retaining strict checks
elsewhere. Use this for notmuch insert --folder, where the empty
string means top level folder.

---

This patch addresses id:87y3owr22c@nikula.org
---
 command-line-arguments.c| 2 +-
 command-line-arguments.h| 3 +++
 doc/man1/notmuch-insert.rst | 3 ++-
 notmuch-insert.c| 2 +-
 4 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/command-line-arguments.c b/command-line-arguments.c
index 1ff5aae578c6..db73ca5efb89 100644
--- a/command-line-arguments.c
+++ b/command-line-arguments.c
@@ -81,7 +81,7 @@ _process_string_arg (const notmuch_opt_desc_t *arg_desc, char 
next, const char *
fprintf (stderr, "Option \"%s\" needs a string argument.\n", 
arg_desc->name);
return false;
 }
-if (arg_str[0] == '\0') {
+if (arg_str[0] == '\0' && ! arg_desc->allow_empty) {
fprintf (stderr, "String argument for option \"%s\" must be 
non-empty.\n", arg_desc->name);
return false;
 }
diff --git a/command-line-arguments.h b/command-line-arguments.h
index 76ca4dcbb276..c0228f7cb634 100644
--- a/command-line-arguments.h
+++ b/command-line-arguments.h
@@ -32,6 +32,9 @@ typedef struct notmuch_opt_desc {
 /* Optional, if non-NULL, set to true if the option is present. */
 bool *present;
 
+/* Optional, allow empty strings for opt_string. */
+bool allow_empty;
+
 /* Must be set for opt_keyword and opt_flags. */
 const struct notmuch_keyword *keywords;
 } notmuch_opt_desc_t;
diff --git a/doc/man1/notmuch-insert.rst b/doc/man1/notmuch-insert.rst
index f79600d6571f..2f2466a6588b 100644
--- a/doc/man1/notmuch-insert.rst
+++ b/doc/man1/notmuch-insert.rst
@@ -34,7 +34,8 @@ Supported options for **insert** include
 ``--folder=<``\ folder\ **>**
 Deliver the message to the specified folder, relative to the
 top-level directory given by the value of **database.path**. The
-default is to deliver to the top-level directory.
+default is the empty string, which means delivering to the
+top-level directory.
 
 ``--create-folder``
 Try to create the folder named by the ``--folder`` option, if it
diff --git a/notmuch-insert.c b/notmuch-insert.c
index 32be74193472..cff74731 100644
--- a/notmuch-insert.c
+++ b/notmuch-insert.c
@@ -463,7 +463,7 @@ notmuch_insert_command (notmuch_config_t *config, int argc, 
char *argv[])
 unsigned int i;
 
 notmuch_opt_desc_t options[] = {
-   { .opt_string = , .name = "folder" },
+   { .opt_string = , .name = "folder", .allow_empty = true },
{ .opt_bool = _folder, .name = "create-folder" },
{ .opt_bool = , .name = "keep" },
{ .opt_bool =  _hooks, .name = "no-hooks" },
-- 
2.11.0

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH 0/3] nmbug:

2017-10-14 Thread Jani Nikula
On Tue, 10 Oct 2017, "W. Trevor King"  wrote:
> I expect the best time to make that bump is just before we cut our
> next notmuch release.  Once we do, we can update the wiki page [1] to
> suggest nmbug 0.3+ and remove the checkout step from “Getting
> started”.

Could we add a "nmbug required version" metadata to the repository, and
add a version check in nmbug? Obviously this doesn't help with 0.2, but,
if we added this at 0.3, we could require a new nmbug version on the
clients.

BR,
Jani.
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [bug] [emacs] notmuch-show: names not shown on some mailing lists

2017-10-14 Thread Jani Nikula
On Tue, 10 Oct 2017, William Casarin  wrote:
> Hey there,
>
> Here's something I've noticed in some mailing list threads in notmuch-show:
>
>   https://jb55.com/s/81d7c740ef60984d.png
>
> It doesn't look like it is showing the correct name.
> Looking at the raw message, the From line looks like this:
>
>   From: Some Person via Some-mailinglist
> 
>   Reply-To: Some Person 
>
> Any way to handle these situations gracefully? Somehow show
> `Some Person` instead of `somemailingl...@lists.linuxfoundation.org`?

The information comes from the cli. Can you reproduce this using some
notmuch show --format=sexp --body=false query, perhaps on just one of
the messages?

BR,
Jani.
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v2 04/10] index: implement notmuch_indexopts_t with try_decrypt

2017-10-14 Thread Jani Nikula
On Mon, 09 Oct 2017, Daniel Kahn Gillmor  wrote:
> On Sat 2017-09-23 19:10:18 +0300, Jani Nikula wrote:
>>> --- a/lib/indexopts.c
>>> +++ b/lib/indexopts.c
>>> @@ -21,9 +21,27 @@
>>>  #include "notmuch-private.h"
>>>  
>>>  notmuch_indexopts_t *
>>> -notmuch_database_get_default_indexopts (notmuch_database_t unused (*db))
>>> +notmuch_database_get_default_indexopts (notmuch_database_t *db)
>>>  {
>>> -return NULL;
>>> +return talloc_zero (db, notmuch_indexopts_t);
>>
>> I wonder about the lifetime of indexopts. Should default indexopts be
>> part of the db object, so that your caller above doesn't have to
>> alloc/destroy it for every file?
>
> The caller doesn't have to alloc/destroy it for every file, they can
> alloc it once and pass it in for every file.

My point was, if the caller doesn't do it, it'll get alloced and
destroyed per file.

BR,
Jani.


>
> I'd rather not have the indexopts be part of the db object itself
> explicitly, because i can imagine a longer-running program wanting to
> create two indexopts objects, configuring them differently, and re-using
> one or the other without wanting to modify the database itself.
>
>> Our library interface has a leaky abstraction of the talloc hierarchical
>> refcounting. We don't talk about it in any of the docs, some of it is
>> implied, most of it is completely surprising if the library interface
>> user assumes a traditional C memory allocation model without
>> refcounting.
>
> right, probably the most surprising thing would be if the user got a
> default indexopts from one database object, and then tried to apply it
> to another database object, after having deleted the first database
> object.
>
> However, we *do* talk about it in the docs now, so i think we've given
> fair warning:
>
> -
> /**
>  * get the current default indexing options for a given database.
>  *
>  * This object will survive until the database itself is destroyed,
>  * but the caller may also release it earlier with
>  * notmuch_indexopts_destroy.
>  *
>  * This object represents a set of options on how a message can be
>  * added to the index.  At the moment it is a featureless stub.
>  *
>  * @since libnotmuch 5.1 (notmuch 0.26)
>  */
> notmuch_indexopts_t *
> notmuch_database_get_default_indexopts (notmuch_database_t *db);
> -
>
> --dkg
___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch


Re: [PATCH v3 10/15] crypto: index encrypted parts when indexopts try_decrypt is set.

2017-10-14 Thread David Bremner
Daniel Kahn Gillmor  writes:

>
> "index.auto.decryption" has at least two different meanings at first
> blush.  For example, it might mean "this message was automatically
> decrypted", which isn't necessarily the case.

I think in either case you need to document what the properties
mean. I don't think "index-decryption" by itself is unambiguous either.

> second confusion:
>
> Even if we used a less ambiguous term like "flush-on-reindex", it would
> seem weird to need to say "notmuch search
> property:index.flush-on-reindex.decryption=failure",

Yes, you seem to envision interactive searching for these
properities. I'll have to take your word for it. I tend to think about
properties as more like APIs than as end user facing.

> We could maybe avoid both of these confusions by dropping "auto"
> altogether and defining the following rule:
>
>  * properties prefixed with "index." are set during indexing and will be
>cleared (and possibly re-set) upon reindexing
>
> wdyt?
>
> If you're ok with that, i could try to update the series to work that
> way (and include documentation along those lines).

I don't object to this.

___
notmuch mailing list
notmuch@notmuchmail.org
https://notmuchmail.org/mailman/listinfo/notmuch