Return-Path: X-Original-To: notmuch@notmuchmail.org Delivered-To: notmuch@notmuchmail.org Received: from localhost (localhost [127.0.0.1]) by olra.theworths.org (Postfix) with ESMTP id E8234431FAF for ; Sat, 21 Jan 2012 14:04:34 -0800 (PST) X-Virus-Scanned: Debian amavisd-new at olra.theworths.org X-Spam-Flag: NO X-Spam-Score: -0.7 X-Spam-Level: X-Spam-Status: No, score=-0.7 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_LOW=-0.7] autolearn=disabled Received: from olra.theworths.org ([127.0.0.1]) by localhost (olra.theworths.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id tRg74xEG--gV for ; Sat, 21 Jan 2012 14:04:34 -0800 (PST) Received: from dmz-mailsec-scanner-5.mit.edu (DMZ-MAILSEC-SCANNER-5.MIT.EDU [18.7.68.34]) by olra.theworths.org (Postfix) with ESMTP id 3C86A431FAE for ; Sat, 21 Jan 2012 14:04:34 -0800 (PST) X-AuditID: 12074422-b7fd66d0000008f9-88-4f1b36712b86 Received: from mailhub-auth-4.mit.edu ( [18.7.62.39]) by dmz-mailsec-scanner-5.mit.edu (Symantec Messaging Gateway) with SMTP id D9.F9.02297.1763B1F4; Sat, 21 Jan 2012 17:04:33 -0500 (EST) Received: from outgoing.mit.edu (OUTGOING-AUTH.MIT.EDU [18.7.22.103]) by mailhub-auth-4.mit.edu (8.13.8/8.9.2) with ESMTP id q0LM4WG0005438; Sat, 21 Jan 2012 17:04:33 -0500 Received: from awakening.csail.mit.edu (awakening.csail.mit.edu [18.26.4.91]) (authenticated bits=0) (User authenticated as amdragon@ATHENA.MIT.EDU) by outgoing.mit.edu (8.13.6/8.12.4) with ESMTP id q0LM4Up6017078 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NOT); Sat, 21 Jan 2012 17:04:31 -0500 (EST) Received: from amthrax by awakening.csail.mit.edu with local (Exim 4.77) (envelope-from ) id 1Roj2d-0008Sa-4N; Sat, 21 Jan 2012 17:04:07 -0500 Date: Sat, 21 Jan 2012 17:04:07 -0500 From: Austin Clements To: Peter Feigl Subject: Re: [PATCH] rewriting notmuch-search for structured output to make other output formats easier Message-ID: <20120121220407.GK16740@mit.edu> References: <1327180568-30385-1-git-send-email-craven@gmx.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1327180568-30385-1-git-send-email-craven@gmx.net> User-Agent: Mutt/1.5.21 (2010-09-15) X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFuphleLIzCtJLcpLzFFi42IRYrdT1y00k/Y3eHRf3mJvQzujxfWbM5kd mDwWb9rP5vFs1S3mAKYoLpuU1JzMstQifbsErozuiz9ZCs6KVdx5MJexgXG9UBcjJ4eEgInE p9vTWCBsMYkL99azgdhCAvsYJZ4ui+9i5AKyNzBKrNq1kh3COckk8WPSXTYIZwmjREfTftYu Rg4OFgFVie5/wiDdbAIaEtv2L2cEsUUEFCSerWsCs5kFpCW+/W5mAikXFsiUuNgeBGLyCuhI LFtqDbHXTmLf3L3MIDavgKDEyZlPWCA6tSRu/HsJ1gkyZfk/DpAwp4C9xPovu9lBbFEBFYkp J7exTWAUmoWkexaS7lkI3QsYmVcxyqbkVunmJmbmFKcm6xYnJ+blpRbpmurlZpbopaaUbmIE B7SL0g7GnweVDjEKcDAq8fAm7JP0F2JNLCuuzD3EKMnBpCTKm2Io7S/El5SfUpmRWJwRX1Sa k1p8iFGCg1lJhLesC6icNyWxsiq1KB8mJc3BoiTOq671zk9IID2xJDU7NbUgtQgmK8PBoSTB +9cUaKhgUWp6akVaZk4JQpqJgxNkOA/Q8HsgNbzFBYm5xZnpEPlTjLocX363nWcUYsnLz0uV EufdA1IkAFKUUZoHNweWiF4xigO9Jcz7FaSKB5jE4Ca9AlrCBLSEI08KZElJIkJKqoHRJ/zc 9zy7d8XCkVOuuEYxV77+8eroU6kdzx8J5hg82cX267k1/wLLv0IBIZc/XhQV/3bN2ITv+9Un huc5BWc/5n1fvMu24dn8D9c7a8Tz1yd86V/OXbX8HsuSw5fn9P41Uz71WNEy7xnPOtVtWgWO sldufRZq/9UYJvHdR2LtX2E3jQf+/RqzlFiKMxINtZiLihMBg0hRsx8DAAA= Cc: notmuch@notmuchmail.org X-BeenThere: notmuch@notmuchmail.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 21 Jan 2012 22:04:35 -0000 Quoth Peter Feigl on Jan 21 at 10:16 pm: > The output routines have been rewritten so that logical structure > (objects with key/value pairs, arrays, strings and numbers) are > written instead of ad-hoc printfs. This allows for easier adaptation > of other output formats, as only the routines that start/end an object > etc. have to be rewritten. The logic is the same for all formats. > The default text output is handled differently, special cases are > inserted at the proper places, as it differs too much from the > structured output. I think this is a great idea and I'm a fan of having an S-expression format, but I also think there's a much easier and more general way to structure this. In particular, I don't think you should hijack search_format, since you'll wind up repeating most of this work for anything else that needs to output structured data (notmuch show, at least). Rather, I'd suggest creating a general "structure printer" struct that isn't tied to search. You've essentially already done this, you just called it search_format. Then, leave the existing format callbacks in place, just use this new API instead of lots of printf calls. What about all of those annoying {tag,item}_{start,sep,end} fields? I think you can simultaneously get rid of those *and* simplify the structure printer API. If the structure printer is allowed to keep a little state, it can automatically insert separators. With a little nesting state, it could even insert terminators by just saying "pop me to this level". This could probably be better, but I'm imagining something like struct sprinter * new_json_sprinter (const void *ctx, FILE *stream); struct sprinter * new_sexp_sprinter (const void *ctx, FILE *stream); /* Start a map (a JSON object or a S-expression alist/plist/whatever) * and return the nesting level of the map. */ int sprinter_map (struct sprinter *sp); /* Start a list (aka array) and return the nesting level of the list. */ int sprinter_list (struct sprinter *sp); /* Close maps and lists until reaching level. */ void sprinter_pop (struct sprinter *sp, int level); void sprinter_map_key (struct sprinter *sp, const char *key); void sprinter_number (struct sprinter *sp, int val); void sprinter_string (struct sprinter *sp, const char *val); void sprinter_bool (struct sprinter *sp, notmuch_bool_t val); and that's it. This would also subsume your format_attribute_* helpers. Unfortunately, it's a pain to pass things like a structure printer object around formatters (too bad notmuch isn't written in C++, eh?). I think it's better to address this than to structure around it. Probably the simplest thing to do is to make a struct for formatter state and pass that in to the callbacks. You could also more completely emulate classes, but that would probably be overkill for this.