--- /dev/null
+Return-Path: <amdragon@mit.edu>\r
+X-Original-To: notmuch@notmuchmail.org\r
+Delivered-To: notmuch@notmuchmail.org\r
+Received: from localhost (localhost [127.0.0.1])\r
+ by olra.theworths.org (Postfix) with ESMTP id A7CA7431FCF\r
+ for <notmuch@notmuchmail.org>; Wed, 23 Oct 2013 12:32:20 -0700 (PDT)\r
+X-Virus-Scanned: Debian amavisd-new at olra.theworths.org\r
+X-Spam-Flag: NO\r
+X-Spam-Score: -0.7\r
+X-Spam-Level: \r
+X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5\r
+ tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled\r
+Received: from olra.theworths.org ([127.0.0.1])\r
+ by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024)\r
+ with ESMTP id Uvyvt3ZzfiBI for <notmuch@notmuchmail.org>;\r
+ Wed, 23 Oct 2013 12:32:15 -0700 (PDT)\r
+Received: from dmz-mailsec-scanner-1.mit.edu (dmz-mailsec-scanner-1.mit.edu\r
+ [18.9.25.12])\r
+ by olra.theworths.org (Postfix) with ESMTP id 23484431FC2\r
+ for <notmuch@notmuchmail.org>; Wed, 23 Oct 2013 12:32:15 -0700 (PDT)\r
+X-AuditID: 1209190c-b7fd38e0000009aa-c9-5268243efa3b\r
+Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])\r
+ by dmz-mailsec-scanner-1.mit.edu (Symantec Messaging Gateway) with SMTP\r
+ id F4.F3.02474.E3428625; Wed, 23 Oct 2013 15:32:14 -0400 (EDT)\r
+Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11])\r
+ by mailhub-auth-3.mit.edu (8.13.8/8.9.2) with ESMTP id r9NJWCTZ008799; \r
+ Wed, 23 Oct 2013 15:32:13 -0400\r
+Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91])\r
+ (authenticated bits=0)\r
+ (User authenticated as amdragon@ATHENA.MIT.EDU)\r
+ by outgoing.mit.edu (8.13.8/8.12.4) with ESMTP id r9NJWAfD029830\r
+ (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);\r
+ Wed, 23 Oct 2013 15:32:11 -0400\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)\r
+ (envelope-from <amdragon@mit.edu>)\r
+ id 1VZ4A5-0006eV-OK; Wed, 23 Oct 2013 15:32:09 -0400\r
+Date: Wed, 23 Oct 2013 15:32:09 -0400\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: Tomi Ollila <tomi.ollila@iki.fi>\r
+Subject: Re: [PATCH 1/3] cli: add insert --must-index option\r
+Message-ID: <20131023193209.GF20337@mit.edu>\r
+References: <1374365254-13227-1-git-send-email-novalazy@gmail.com>\r
+ <87ip048gbj.fsf@qmul.ac.uk>\r
+ <20130727151510.GA13750@hili.localdomain>\r
+ <87hadtxfrr.fsf@qmul.ac.uk>\r
+ <20130912001349.GA18821@hili.localdomain>\r
+ <87zjqhv264.fsf@zancas.localnet>\r
+ <m238o9fguj.fsf@guru.guru-group.fi> <87bo2xtdp2.fsf@unb.ca>\r
+ <m2eh7bu7t5.fsf@guru.guru-group.fi>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=iso-8859-1\r
+Content-Disposition: inline\r
+Content-Transfer-Encoding: 8bit\r
+In-Reply-To: <m2eh7bu7t5.fsf@guru.guru-group.fi>\r
+User-Agent: Mutt/1.5.21 (2010-09-15)\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFlrOKsWRmVeSWpSXmKPExsUixCmqrWunkhFkcO+DisWN1m5Gi+s3ZzJb\r
+ vFk5j9WB2ePw14UsHs9W3WL22HLoPXMAcxSXTUpqTmZZapG+XQJXRnfXd7aCryoVn95OYG5g\r
+ PCrTxcjJISFgIvFn8VYmCFtM4sK99WxdjFwcQgL7GCXOr3zADuFsZJS48mMnM4Rzmkmi+9Zc\r
+ RghnCaPEtjnzwPpZBFQlDsx9xQ5iswloSGzbv5wRxBYRUJF40LaeFcRmFrCTOPK9CywuLGAj\r
+ 0T37JRuIzSugI/H0yBqoofeZJJbdaWOGSAhKnJz5hAWiWUdi59Y7QA0cQLa0xPJ/HBBheYnm\r
+ rbPByjkFDCTeHd8Ndo8o0N4pJ7exTWAUnoVk0iwkk2YhTJqFZNICRpZVjLIpuVW6uYmZOcWp\r
+ ybrFyYl5ealFuoZ6uZkleqkppZsYwfEhybOD8c1BpUOMAhyMSjy8Gh/Sg4RYE8uKK3MPMUpy\r
+ MCmJ8uopZwQJ8SXlp1RmJBZnxBeV5qQWH2KU4GBWEuF98geonDclsbIqtSgfJiXNwaIkznuT\r
+ wz5ISCA9sSQ1OzW1ILUIJivDwaEkwWsBMlSwKDU9tSItM6cEIc3EwQkynAdouBlIDW9xQWJu\r
+ cWY6RP4Uo6KUOO9VJaCEAEgiozQPrheWvl4xigO9IszLAdLOA0x9cN2vgAYzAQ2esiQNZHBJ\r
+ IkJKqoGxy/uv5+ojzNcuKaxx9VoxP2XersytIa330+I6k1X8Gp7sVNV+YOYdePFR2pltgv4J\r
+ N3K0f15tYeA3d1omulPPJih8ctBE6UD+rT2Cd2MXpOf+1D7iHSL7UuNHvyBX2pRfX5eskC8p\r
+ /mKQLfN/oq3rvZWnwr3lOzpsd63/VtuwfRVb/fmPjIuVWIozEg21mIuKEwEz2/mLOgMAAA==\r
+Cc: notmuch@notmuchmail.org\r
+X-BeenThere: notmuch@notmuchmail.org\r
+X-Mailman-Version: 2.1.13\r
+Precedence: list\r
+List-Id: "Use and development of the notmuch mail system."\r
+ <notmuch.notmuchmail.org>\r
+List-Unsubscribe: <http://notmuchmail.org/mailman/options/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=unsubscribe>\r
+List-Archive: <http://notmuchmail.org/pipermail/notmuch>\r
+List-Post: <mailto:notmuch@notmuchmail.org>\r
+List-Help: <mailto:notmuch-request@notmuchmail.org?subject=help>\r
+List-Subscribe: <http://notmuchmail.org/mailman/listinfo/notmuch>,\r
+ <mailto:notmuch-request@notmuchmail.org?subject=subscribe>\r
+X-List-Received-Date: Wed, 23 Oct 2013 19:32:20 -0000\r
+\r
+Quoth Tomi Ollila on Oct 23 at 10:05 pm:\r
+> On Thu, Oct 10 2013, David Bremner <david@tethera.net> wrote:\r
+> \r
+> > Tomi Ollila <tomi.ollila@iki.fi> writes:\r
+> >>> I'm not opposed to doing an SONAME bump for 0.17. Are there other ABI\r
+> >>> breaking changes that we have been holding back on? Can these maybe go\r
+> >>> through at the same time?\r
+> >>\r
+> >> Maybe something along these lines...\r
+> >>\r
+> >> (Quick draft for the API part; to start discussion before working too much\r
+> >> for something that is going to be dropped...)\r
+> >>\r
+> >> notmuch_status_t\r
+> >> -notmuch_database_create (const char *path, notmuch_database_t **database);\r
+> >> +notmuch_database_create (const char *path,\r
+> >> + notmuch_loghook_t *loghook,\r
+> >> + notmuch_database_t **database);\r
+> >\r
+> > Another idea floated (by Austin?) was to pass in an options struct, to\r
+> > allow future options to be added without changing the function\r
+> > signature. I guess with some care this could be done in an upwardly\r
+> > compatible way.\r
+> \r
+> Maybe something like\r
+> \r
+> #define NOTMUCH_API_OPTIONS_VERSION 1\r
+> typedef struct {\r
+> int options_version;\r
+> void (*log)(void *, int level, int status, const char * format, ...);\r
+> void * logdata;\r
+> } notmuch_options_t; \r
+> \r
+> ...\r
+> \r
+> notmuch_status_t\r
+> notmuch_database_create (const char *path,\r
+> notmuch_options_t *options,\r
+> notmuch_database_t **database);\r
+> ...\r
+> \r
+> notmuch_status_t\r
+> notmuch_database_open (const char *path,\r
+> notmuch_database_mode_t mode,\r
+> notmuch_options_t *options,\r
+> notmuch_database_t **database);\r
+> \r
+> then in use:\r
+> \r
+> notmuch_options_t options = {\r
+> .options_version = NOTMUCH_API_OPTIONS_VERSION,\r
+> \r
+> .. äsh, this has problem that the macro changes in header file\r
+> but the structure initialization is not following automatically\r
+> (in other fields than that). Therefore perhaps "fixing"\r
+> the version macros:\r
+> \r
+> #define NOTMUCH_API_OPTIONS_VERSION_1 1\r
+> /* #define NOTMUCH_API_OPTIONS_VERSION_2 2 // added in the future */\r
+> \r
+> notmuch_options_t options = {\r
+> .options_version = NOTMUCH_API_OPTIONS_VERSION_1,\r
+> .log = log_to_stderr,\r
+> .logdata = NULL\r
+> };\r
+> \r
+> Well, this is one idea (does not sound as good as I initially\r
+> thought...) how does other software tackle this kind of issues...\r
+> \r
+> If something like this is finally chosen we could provide easy\r
+> transition path to allow NULL as options -- making notmuch CLI\r
+> behave as it used to be (log to stderr...).\r
+\r
+Using a version number on the options makes it tricky to maintain\r
+backwards compatibility, since you need code to read all past versions\r
+of the structure. A similar but, I think, better way would be to take\r
+the size of the structure in the structure. Something like:\r
+\r
+typedef struct {\r
+ size_t options_length;\r
+ ...\r
+} notmuch_options_t;\r
+\r
+#define NOTMUCH_OPTIONS_INIT { sizeof(notmuch_options_t) }\r
+// or without pre-processor, but requiring GCC attributes\r
+static __attribute__((__unused__))\r
+notmuch_options_t notmuch_options_init = { sizeof(notmuch_options_t) };\r
+\r
+NOTMUCH_OPTIONS_INIT/notmuch_options_init could also contain other\r
+defaults, though it's best if the defaults are simply the zero\r
+initializations of the various fields.\r
+\r
+\r
+Then, in code calling libnotmuch, you'd do something like\r
+\r
+notmuch_options_t options = NOTMUCH_OPTIONS_INIT;\r
+options.log = log_to_stderr;\r
+// ...\r
+\r
+\r
+And in libnotmuch, we would do something like\r
+\r
+notmuch_status_t\r
+notmuch_database_open (const char *path,\r
+ notmuch_database_mode_t mode,\r
+ const notmuch_options_t *options,\r
+ notmuch_database_t **database)\r
+{\r
+ notmuch_option_t real_options = NOTMUCH_OPTIONS_INIT;\r
+ if (real_options.options_length < options.options_length)\r
+ return error;\r
+ memmove(&real_options, options, options.options_length);\r
+ // ...\r
+}\r
+\r
+This approach makes it free to add fields and we can always deprecate\r
+fields as long as we leave the space in the structure. This is based\r
+roughly on how the Linux kernel deals with various structures that\r
+have grown over time in the syscall ABI.\r
+\r
+Another much more verbose but also more robust approach would be to\r
+make notmuch_options_t opaque and provide setters (and getters, if\r
+we're feeling benevolent). I kind of like the simplicity of a struct.\r
+\r
+One thing to consider is what works best with bindings. Presumably\r
+the opaque structure wouldn't be a problem. I've never had to wrap\r
+anything like the struct approach, though, so I don't know if that's\r
+easy or hard.\r