Re: [Patch v5 3/6] util: add gz_readline
authorAustin Clements <amdragon@MIT.EDU>
Wed, 2 Apr 2014 03:26:44 +0000 (23:26 +2000)
committerW. Trevor King <wking@tremily.us>
Fri, 7 Nov 2014 18:01:09 +0000 (10:01 -0800)
49/897b3847c02d5e3ca038a999b6a049664b0c9a [new file with mode: 0644]

diff --git a/49/897b3847c02d5e3ca038a999b6a049664b0c9a b/49/897b3847c02d5e3ca038a999b6a049664b0c9a
new file mode 100644 (file)
index 0000000..13ea5a6
--- /dev/null
@@ -0,0 +1,253 @@
+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 8BD82431FBF\r
+       for <notmuch@notmuchmail.org>; Tue,  1 Apr 2014 20:26:56 -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 arQb2BlrWfO3 for <notmuch@notmuchmail.org>;\r
+       Tue,  1 Apr 2014 20:26:48 -0700 (PDT)\r
+Received: from dmz-mailsec-scanner-2.mit.edu (dmz-mailsec-scanner-2.mit.edu\r
+       [18.9.25.13])\r
+       (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\r
+       (No client certificate requested)\r
+       by olra.theworths.org (Postfix) with ESMTPS id 86B08431FBD\r
+       for <notmuch@notmuchmail.org>; Tue,  1 Apr 2014 20:26:48 -0700 (PDT)\r
+X-AuditID: 1209190d-f79776d000000ce9-3a-533b83778d2e\r
+Received: from mailhub-auth-3.mit.edu ( [18.9.21.43])\r
+       (using TLS with cipher AES256-SHA (256/256 bits))\r
+       (Client did not present a certificate)\r
+       by dmz-mailsec-scanner-2.mit.edu (Symantec Messaging Gateway) with SMTP\r
+       id F4.61.03305.7738B335; Tue,  1 Apr 2014 23:26:47 -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 s323QkkI020348; \r
+       Tue, 1 Apr 2014 23:26:47 -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 s323Qi9D007890\r
+       (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NOT);\r
+       Tue, 1 Apr 2014 23:26:46 -0400\r
+Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.80)\r
+       (envelope-from <amdragon@mit.edu>)\r
+       id 1WVBp6-0004YY-MZ; Tue, 01 Apr 2014 23:26:44 -0400\r
+Date: Tue, 1 Apr 2014 23:26:44 -0400\r
+From: Austin Clements <amdragon@MIT.EDU>\r
+To: David Bremner <david@tethera.net>\r
+Subject: Re: [Patch v5 3/6] util: add gz_readline\r
+Message-ID: <20140402032644.GB25677@mit.edu>\r
+References: <1396401381-18128-1-git-send-email-david@tethera.net>\r
+       <1396401381-18128-4-git-send-email-david@tethera.net>\r
+MIME-Version: 1.0\r
+Content-Type: text/plain; charset=us-ascii\r
+Content-Disposition: inline\r
+In-Reply-To: <1396401381-18128-4-git-send-email-david@tethera.net>\r
+User-Agent: Mutt/1.5.21 (2010-09-15)\r
+X-Brightmail-Tracker:\r
+ H4sIAAAAAAAAA+NgFuplleLIzCtJLcpLzFFi42IR4hTV1i1vtg42uDRL2+JGazejxfWbM5kd\r
+       mDyerbrF7LHl0HvmAKYoLpuU1JzMstQifbsEroye3RfYCuZrVJxqdWlg/CPXxcjJISFgIjH/\r
+       7EM2CFtM4sK99UA2F4eQwGwmiZ6mzUwQzgZGiUfHlzGDVAkJnGKS2LTKDMJewihx7LINiM0i\r
+       oCLRvb6ZBcRmE9CQ2LZ/OSOILSKgKnF122SwDcwC0hLffjczgdjCAoYS/5c9A6vnFdCROLJh\r
+       NwvEzEqJnvWLmCDighInZz5hgejVkrjx7yVQnANszvJ/HCBhTgEniTentoOViAKdMOXkNrYJ\r
+       jEKzkHTPQtI9C6F7ASPzKkbZlNwq3dzEzJzi1GTd4uTEvLzUIl0jvdzMEr3UlNJNjOCQluTd\r
+       wfjuoNIhRgEORiUe3gPnrYKFWBPLiitzDzFKcjApifJyBFsHC/El5adUZiQWZ8QXleakFh9i\r
+       lOBgVhLh/e4LlONNSaysSi3Kh0lJc7AoifO+tQaaJJCeWJKanZpakFoEk5Xh4FCS4PVuAmoU\r
+       LEpNT61Iy8wpQUgzcXCCDOcBGi4HUsNbXJCYW5yZDpE/xajL8WnDmkYmIZa8/LxUKXFeJZAi\r
+       AZCijNI8uDmwVPSKURzoLWFefZAqHmAag5v0CmgJE9AS7nVWIEtKEhFSUg2Mgs4FZ5daeLgt\r
+       dOeolJQ5M2PjL955fR9qWCLXLJ5ofZx5h+eVsLIbBZ5OhW1hLtuWrwg6f7W/fPVfpROf2cv3\r
+       K2289PP58n2f0o9NKD9r1vJ0A1v6vE59pXfWq7rYsy/PNtC/IJYv4yGUOsPI7Ue8s6AIn0ty\r
+       fOKHbvPcczKZB5mMb/C8lVdSYinOSDTUYi4qTgQARaRAISADAAA=\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, 02 Apr 2014 03:26:56 -0000\r
+\r
+Quoth David Bremner on Apr 01 at 10:16 pm:\r
+> The idea is to provide a more or less drop in replacement for readline\r
+> to read from zlib/gzip streams.  Take the opportunity to replace\r
+> malloc with talloc.\r
+> ---\r
+>  util/Makefile.local |  2 +-\r
+>  util/util.h         | 12 +++++++++\r
+>  util/zlib-extra.c   | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++\r
+>  util/zlib-extra.h   | 11 ++++++++\r
+>  4 files changed, 100 insertions(+), 1 deletion(-)\r
+>  create mode 100644 util/util.h\r
+>  create mode 100644 util/zlib-extra.c\r
+>  create mode 100644 util/zlib-extra.h\r
+> \r
+> diff --git a/util/Makefile.local b/util/Makefile.local\r
+> index 29c0ce6..e2a5b65 100644\r
+> --- a/util/Makefile.local\r
+> +++ b/util/Makefile.local\r
+> @@ -4,7 +4,7 @@ dir := util\r
+>  extra_cflags += -I$(srcdir)/$(dir)\r
+>  \r
+>  libutil_c_srcs := $(dir)/xutil.c $(dir)/error_util.c $(dir)/hex-escape.c \\r
+> -              $(dir)/string-util.c $(dir)/talloc-extra.c\r
+> +              $(dir)/string-util.c $(dir)/talloc-extra.c $(dir)/zlib-extra.c\r
+>  \r
+>  libutil_modules := $(libutil_c_srcs:.c=.o)\r
+>  \r
+> diff --git a/util/util.h b/util/util.h\r
+> new file mode 100644\r
+> index 0000000..8663cfc\r
+> --- /dev/null\r
+> +++ b/util/util.h\r
+> @@ -0,0 +1,12 @@\r
+> +#ifndef _UTIL_H\r
+> +#define _UTIL_H\r
+> +\r
+> +typedef enum util_status {\r
+> +    UTIL_SUCCESS = 0,\r
+> +    UTIL_ERROR = 1,\r
+> +    UTIL_OUT_OF_MEMORY,\r
+> +    UTIL_EOF,\r
+> +    UTIL_FILE,\r
+> +} util_status_t;\r
+> +\r
+> +#endif\r
+> diff --git a/util/zlib-extra.c b/util/zlib-extra.c\r
+> new file mode 100644\r
+> index 0000000..cb1eba0\r
+> --- /dev/null\r
+> +++ b/util/zlib-extra.c\r
+> @@ -0,0 +1,76 @@\r
+> +/* zlib-extra.c -  Extra or enhanced routines for compressed I/O.\r
+> + *\r
+> + * Copyright (c) 2014 David Bremner\r
+> + *\r
+> + * This program is free software: you can redistribute it and/or modify\r
+> + * it under the terms of the GNU General Public License as published by\r
+> + * the Free Software Foundation, either version 3 of the License, or\r
+> + * (at your option) any later version.\r
+> + *\r
+> + * This program is distributed in the hope that it will be useful,\r
+> + * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+> + * GNU General Public License for more details.\r
+> + *\r
+> + * You should have received a copy of the GNU General Public License\r
+> + * along with this program.  If not, see http://www.gnu.org/licenses/ .\r
+> + *\r
+> + * Author: David Bremner <david@tethera.net>\r
+> + */\r
+> +\r
+> +#include "zlib-extra.h"\r
+> +#include <talloc.h>\r
+> +#include <stdio.h>\r
+> +#include <string.h>\r
+> +\r
+> +/* mimic POSIX/glibc getline, but on a zlib gzFile stream, and using talloc */\r
+> +util_status_t\r
+> +gz_getline (void *talloc_ctx, char **bufptr, size_t *bufsiz, ssize_t *bytes_read,\r
+\r
+Talloc chunks know their size, so rather than taking bufsize, use\r
+talloc_get_size (or talloc_array_length if you switch to talloc array\r
+functions below).\r
+\r
+> +        gzFile stream)\r
+> +{\r
+> +    size_t len = *bufsiz;\r
+> +    char *buf = *bufptr;\r
+> +    size_t offset = 0;\r
+> +\r
+> +    if (len == 0 || buf == NULL) {\r
+> +    /* same as getdelim from gnulib */\r
+> +    len = 120;\r
+\r
+This is presumably because glibc's malloc has an 8 byte header.  Fun\r
+fact: talloc has a 104 byte header (on 64-bit and including the malloc\r
+header).\r
+\r
+> +    buf = talloc_size (talloc_ctx, len);\r
+> +    if (buf == NULL)\r
+> +        return UTIL_OUT_OF_MEMORY;\r
+> +    }\r
+> +\r
+> +    while (1) {\r
+> +    if (! gzgets (stream, buf + offset, len - offset)) {\r
+> +        int zlib_status = 0;\r
+> +        (void) gzerror (stream, &zlib_status);\r
+> +        switch (zlib_status) {\r
+> +        case Z_OK:\r
+> +            /* follow getline behaviour */\r
+> +            *bytes_read = -1;\r
+\r
+Is this really what getline does when the last line of a file isn't\r
+\n-terminated?\r
+\r
+> +            return UTIL_EOF;\r
+> +            break;\r
+> +        case Z_ERRNO:\r
+> +            return UTIL_FILE;\r
+> +            break;\r
+> +        default:\r
+> +            return UTIL_ERROR;\r
+> +        }\r
+> +    }\r
+> +\r
+> +    offset += strlen (buf + offset);\r
+> +\r
+> +    if ( buf[offset - 1] == '\n' )\r
+\r
+Too many spaces!\r
+\r
+> +        break;\r
+> +\r
+> +    len *= 2;\r
+> +    buf = talloc_realloc (talloc_ctx, buf, char, len);\r
+\r
+Or talloc_realloc_size, to match the initial talloc_size.\r
+Alternatively, the initial talloc_size could be a talloc_array.\r
+\r
+> +    if (buf == NULL)\r
+> +        return UTIL_OUT_OF_MEMORY;\r
+> +    }\r
+> +\r
+> +    *bufptr = buf;\r
+> +    *bufsiz = len;\r
+> +    *bytes_read = offset;\r
+> +    return UTIL_SUCCESS;\r
+> +}\r
+> diff --git a/util/zlib-extra.h b/util/zlib-extra.h\r
+> new file mode 100644\r
+> index 0000000..ed46ac1\r
+> --- /dev/null\r
+> +++ b/util/zlib-extra.h\r
+> @@ -0,0 +1,11 @@\r
+> +#ifndef _ZLIB_EXTRA_H\r
+> +#define _ZLIB_EXTRA_H\r
+> +\r
+> +#include <zlib.h>\r
+> +#include "util.h"\r
+\r
+I'd put "util.h" first so we're more likely to catch missing header\r
+dependencies (obviously util.h doesn't have any right now, but in the\r
+future).\r
+\r
+Also, I'd put a blank line after the #includes.\r
+\r
+> +/* Like getline, but read from a gzFile. Allocation is with talloc */\r
+> +util_status_t\r
+> +gz_getline (void *ctx, char **lineptr, size_t *line_size, ssize_t *bytes_read,\r
+> +        gzFile stream);\r
+> +\r
+> +#endif\r