Re: [PATCH v3 2/5] util: Function to parse boolean term queries
authorAustin Clements <amdragon@MIT.EDU>
Mon, 31 Dec 2012 05:52:17 +0000 (00:52 +1900)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 17:52:53 +0000 (09:52 -0800)
12/ddcd28cfd161e676545ea4a65908acbb97528e [new file with mode: 0644]

diff --git a/12/ddcd28cfd161e676545ea4a65908acbb97528e b/12/ddcd28cfd161e676545ea4a65908acbb97528e
new file mode 100644 (file)
index 0000000..e156fdf
--- /dev/null
@@ -0,0 +1,208 @@
+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 8032A431FB6\r
+       for <notmuch@notmuchmail.org>; Sun, 30 Dec 2012 21:52:24 -0800 (PST)\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 V-44hOknVuAK for <notmuch@notmuchmail.org>;\r
+       Sun, 30 Dec 2012 21:52:23 -0800 (PST)\r
+Received: from dmz-mailsec-scanner-7.mit.edu (DMZ-MAILSEC-SCANNER-7.MIT.EDU\r
+       [18.7.68.36])\r
+       by olra.theworths.org (Postfix) with ESMTP id 1836E431FAF\r
+       for <notmuch@notmuchmail.org>; Sun, 30 Dec 2012 21:52:23 -0800 (PST)\r
+X-AuditID: 12074424-b7f4e6d0000004ca-7e-50e128149662\r
+Received: from mailhub-auth-1.mit.edu ( [18.9.21.35])\r
+       by dmz-mailsec-scanner-7.mit.edu (Symantec Messaging Gateway) with SMTP\r
+       id 3C.80.01226.41821E05; Mon, 31 Dec 2012 00:52:20 -0500 (EST)\r
+Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103])\r
+       by mailhub-auth-1.mit.edu (8.13.8/8.9.2) with ESMTP id qBV5qKr4025387; \r
+       Mon, 31 Dec 2012 00:52:20 -0500\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.6/8.12.4) with ESMTP id qBV5qHf6006487\r
+       (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);\r
+       Mon, 31 Dec 2012 00:52:19 -0500 (EST)\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)\r
+       (envelope-from <amdragon@mit.edu>)\r
+       id 1TpYIL-0007eU-Ay; Mon, 31 Dec 2012 00:52:17 -0500\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: Tomi Ollila <tomi.ollila@iki.fi>, notmuch@notmuchmail.org\r
+Subject: Re: [PATCH v3 2/5] util: Function to parse boolean term queries\r
+In-Reply-To: <m2han4sepu.fsf@guru.guru-group.fi>\r
+References: <1356719189-2837-1-git-send-email-amdragon@mit.edu>\r
+       <1356719189-2837-3-git-send-email-amdragon@mit.edu>\r
+       <m2han4sepu.fsf@guru.guru-group.fi>\r
+User-Agent: Notmuch/0.14+236~gf64406d (http://notmuchmail.org) Emacs/23.4.1\r
+       (i486-pc-linux-gnu)\r
+Date: Mon, 31 Dec 2012 00:52:17 -0500\r
+Message-ID: <87a9sulqem.fsf@awakening.csail.mit.edu>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFnrAIsWRmVeSWpSXmKPExsUixCmqrCui8TDAYP9Ma4vrN2cyW7xZOY/V\r
+       gcnj8NeFLB7PVt1iDmCK4rJJSc3JLEst0rdL4Mo49ymmYLdixctfr5gbGA9IdjFycEgImEhs\r
+       OVzWxcgJZIpJXLi3ng3EFhLYxyjR+IGzi5ELyN7AKLHw0QMmCOcik8SiyQ0sEM4SRompvcvZ\r
+       QVrYBDQktu1fzghiiwjYSlxZcpIVxBYW8JDYuPEsE4jNKWAg8ej0U3aI5umMEi1rHoIlRAXi\r
+       JZ7f+8YCYrMIqErMXb6ZGcTmBTpv3b1J7BC2oMTJmU/AapgFtCRu/HvJNIFRYBaS1CwkqQWM\r
+       TKsYZVNyq3RzEzNzilOTdYuTE/PyUot0zfVyM0v0UlNKNzGCApLdRWUHY/MhpUOMAhyMSjy8\r
+       G/4/CBBiTSwrrsw9xCjJwaQkyquu/DBAiC8pP6UyI7E4I76oNCe1+BCjBAezkgjv0XlA5bwp\r
+       iZVVqUX5MClpDhYlcd7rKTf9hQTSE0tSs1NTC1KLYLIyHBxKErxa6kBDBYtS01Mr0jJzShDS\r
+       TBycIMN5gIabgtTwFhck5hZnpkPkTzEqSonzioEkBEASGaV5cL2whPGKURzoFWFeIZAqHmCy\r
+       get+BTSYCWiwFgPI1cUliQgpqQZGj/5foq4lzgzHljXNUprd0utrdLRePXbiI84oibNxsSkt\r
+       j5+8emDRt/+Nnc8jWZkzrNUxbZ+zCvQTVob9nidut2jv4iMzN3PuzpfVsp/y5OKit00WV/5w\r
+       XFlz/n4lo23u7UnzfNes+dL3qtXzghLDhV/VTLMjKsuCGNU8jt7d6exqPGfxvVg7JZbijERD\r
+       Leai4kQA9lwoOfMCAAA=\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: Mon, 31 Dec 2012 05:52:24 -0000\r
+\r
+On Sat, 29 Dec 2012, Tomi Ollila <tomi.ollila@iki.fi> wrote:\r
+> On Fri, Dec 28 2012, Austin Clements <amdragon@MIT.EDU> wrote:\r
+>\r
+>> This parses the subset of Xapian's boolean term quoting rules that are\r
+>> used by make_boolean_term.  This is provided as a generic string\r
+>> utility, but will be used shortly in notmuch restore to parse and\r
+>> optimize for ID queries.\r
+>> ---\r
+>>  util/string-util.c |   55 ++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+>>  util/string-util.h |   11 +++++++++++\r
+>>  2 files changed, 66 insertions(+)\r
+>>\r
+>> diff --git a/util/string-util.c b/util/string-util.c\r
+>> index e4bea21..83b4953 100644\r
+>> --- a/util/string-util.c\r
+>> +++ b/util/string-util.c\r
+>> @@ -96,3 +96,58 @@ make_boolean_term (void *ctx, const char *prefix, const char *term,\r
+>>  \r
+>>      return 0;\r
+>>  }\r
+>> +\r
+>> +int\r
+>> +parse_boolean_term (void *ctx, const char *str,\r
+>> +               char **prefix_out, char **term_out)\r
+>> +{\r
+>> +    *prefix_out = *term_out = NULL;\r
+>> +\r
+>> +    /* Parse prefix */\r
+>> +    const char *pos = strchr (str, ':');\r
+>> +    if (! pos)\r
+>> +   goto FAIL;\r
+>> +    *prefix_out = talloc_strndup (ctx, str, pos - str);\r
+>> +    ++pos;\r
+>> +\r
+>> +    /* Implement de-quoting compatible with make_boolean_term. */\r
+>> +    if (*pos == '"') {\r
+>> +   char *out = talloc_array (ctx, char, strlen (pos));\r
+>> +   int closed = 0;\r
+>> +   *term_out = out;\r
+>> +   /* Skip the opening quote, find the closing quote, and\r
+>> +    * un-double doubled internal quotes. */\r
+>> +   for (++pos; *pos; ) {\r
+>> +       if (*pos == '"') {\r
+>> +           ++pos;\r
+>> +           if (*pos != '"') {\r
+>> +               /* Found the closing quote. */\r
+>> +               closed = 1;\r
+>> +               break;\r
+>> +           }\r
+>> +       }\r
+>> +       *out++ = *pos++;\r
+>> +   }\r
+>> +   /* Did the term terminate without a closing quote or is there\r
+>> +    * trailing text after the closing quote? */\r
+>> +   if (!closed || *pos)\r
+>> +       goto FAIL;\r
+>> +   *out = '\0';\r
+>> +    } else {\r
+>> +   const char *start = pos;\r
+>> +   /* Check for text after the boolean term. */\r
+>> +   while (*pos > ' ' && *pos != ')')\r
+>> +       ++pos;\r
+>> +   if (*pos)\r
+>> +       goto FAIL;\r
+>\r
+> Mark pointed out a good case about trailing whitespace -- It would be nice\r
+> if the core were lenient for such cases. I personally remember once wasting\r
+> hours of work by just failing to notice trailing whitespace in one system\r
+> so this subject is sensitive to me...\r
+\r
+Will do.\r
+\r
+> Another thing I saw earlyer today: make_boolean_term() checks\r
+>\r
+>    if (*in <= ' ' || *in == ')' || *in == '"' || (unsigned char)*in > 127)\r
+>\r
+> but here the check is only\r
+>\r
+>    while (*pos > ' ' && *pos != ')')\r
+>\r
+> I wonder whether it matters...\r
+\r
+This is correct in a conservative way.  We quote things that we don't\r
+strictly need to quote (for example, a double quote in the middle of a\r
+term doesn't actually require the term to be quoted, but we do anyway),\r
+but we look for the end of an unquoted term in exactly the same way\r
+Xapian does.\r
+\r
+> Everyting else looks good to me.\r
+>\r
+>\r
+> Tomi\r
+>\r
+>> +   /* No trailing text; dup the string so the caller can free\r
+>> +    * it. */\r
+>> +   *term_out = talloc_strdup (ctx, start);\r
+>> +    }\r
+>> +    return 0;\r
+>> +\r
+>> + FAIL:\r
+>> +    talloc_free (*prefix_out);\r
+>> +    talloc_free (*term_out);\r
+>> +    return 1;\r
+>> +}\r
+>> diff --git a/util/string-util.h b/util/string-util.h\r
+>> index b8844a3..43d49d0 100644\r
+>> --- a/util/string-util.h\r
+>> +++ b/util/string-util.h\r
+>> @@ -33,4 +33,15 @@ char *strtok_len (char *s, const char *delim, size_t *len);\r
+>>  int make_boolean_term (void *talloc_ctx, const char *prefix, const char *term,\r
+>>                    char **buf, size_t *len);\r
+>>  \r
+>> +/* Parse a boolean term query produced by make_boolean_term, returning\r
+>> + * the prefix in *prefix_out and the term in *term_out.  *prefix_out\r
+>> + * and *term_out will be talloc'd with context ctx.\r
+>> + *\r
+>> + * Return: 0 on success, non-zero on parse error (including trailing\r
+>> + * data in str).\r
+>> + */\r
+>> +int\r
+>> +parse_boolean_term (void *ctx, const char *str,\r
+>> +               char **prefix_out, char **term_out);\r
+>> +\r
+>>  #endif\r
+>> -- \r
+>> 1.7.10.4\r
+>>\r
+>> _______________________________________________\r
+>> notmuch mailing list\r
+>> notmuch@notmuchmail.org\r
+>> http://notmuchmail.org/mailman/listinfo/notmuch\r