From: craven Date: Tue, 10 Jul 2012 18:56:09 +0000 (+0200) Subject: [PATCH v3 1/3] Add support for structured output formatters. X-Git-Url: http://git.tremily.us/gitweb.cgi?a=commitdiff_plain;h=bf347344a6e9883a1e3cc88491595c336663be83;p=notmuch-archives.git [PATCH v3 1/3] Add support for structured output formatters. --- diff --git a/df/ea1c70b51ab15fe794e5191e21347e6eb7c754 b/df/ea1c70b51ab15fe794e5191e21347e6eb7c754 new file mode 100644 index 000000000..a0ae390eb --- /dev/null +++ b/df/ea1c70b51ab15fe794e5191e21347e6eb7c754 @@ -0,0 +1,202 @@ +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 8EC86431FC0 + for ; Tue, 10 Jul 2012 11:56:14 -0700 (PDT) +X-Virus-Scanned: Debian amavisd-new at olra.theworths.org +X-Spam-Flag: NO +X-Spam-Score: 0.001 +X-Spam-Level: +X-Spam-Status: No, score=0.001 tagged_above=-999 required=5 + tests=[FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001] + 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 Rdh+vVmivbtq for ; + Tue, 10 Jul 2012 11:56:13 -0700 (PDT) +Received: from mailout-de.gmx.net (mailout-de.gmx.net [213.165.64.23]) + by olra.theworths.org (Postfix) with SMTP id 4C6AA431FBF + for ; Tue, 10 Jul 2012 11:56:13 -0700 (PDT) +Received: (qmail invoked by alias); 10 Jul 2012 18:56:10 -0000 +Received: from www.nexoid.at (EHLO mail.nexoid.at) [178.79.130.240] + by mail.gmx.net (mp031) with SMTP; 10 Jul 2012 20:56:10 +0200 +X-Authenticated: #4563876 +X-Provags-ID: V01U2FsdGVkX19Vb2BisVBVkwwxE2kmexZLYEysiJVDAUaGlOF67S + B+XR9dIoYuJIEG +Received: from nexoid (localhost [127.0.0.1]) + by mail.nexoid.at (Postfix) with ESMTP id 4C6AAE00C + for ; Tue, 10 Jul 2012 20:56:09 +0200 (CEST) +From: +To: notmuch@notmuchmail.org +Subject: [PATCH v3 1/3] Add support for structured output formatters. +User-Agent: Notmuch/0.11+77~gad6d0d5 (http://notmuchmail.org) Emacs/24.1.50.2 + (i686-pc-linux-gnu) +Date: Tue, 10 Jul 2012 20:56:09 +0200 +Message-ID: <87394zv41i.fsf@nexoid.at> +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf-8 +Content-Transfer-Encoding: quoted-printable +X-Y-GMX-Trusted: 0 +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: Tue, 10 Jul 2012 18:56:14 -0000 + +This patch adds a new type structure_printer, which is used for structured = +formatting, e.g. JSON or S-Expressions. + +The structure contains the following function pointers: + +- initial_state: is called to create a state object, that is passed to all = +invocations. This should be used to keep track of the output file and every= +thing else necessary to correctly format output. +- map: is called when a new map (associative array, dictionary) is started.= + map_key and the primitives (string, number, bool) are used alternatingly t= +o add key/value pairs. pop is used to close the map (see there). This funct= +ion must return a nesting level identifier that can be used to close all ne= +sted structures (maps and lists), backing out to the returned nesting level. +- list: is called when a new list (array, vector) is started. the primitive= +s (string, number, bool) are used consecutively to add values to the list. = +pop is used to close the list. This function must return a nesting level id= +entifier that can be used to close all nested structures (maps and lists), = +backing out to the returned nesting level. +- pop: is called to return to a given nesting level. All lists and maps wit= +h a deeper nesting level must be closed. +- number, string, bool: output one element of the specific type. + +All functions should use state to insert delimiters etc. automatically when= + appropriate. + +Example: +int top, one; +top =3D map(state); +map_key(state, "foo"); +one =3D list(state); +number(state, 1); +number(state, 2); +number(state, 3); +pop(state, one); +map_key(state, "bar"); +map(state); +map_key(state, "baaz"); +string(state, "hello world"); +pop(state, top); + +would output JSON as follows: + +{"foo": [1, 2, 3], "bar": { "baaz": "hello world"}} +--- + Makefile.local | 1 + + structured-output.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++= +++++ + 2 files changed, 65 insertions(+) + create mode 100644 structured-output.h + +diff --git a/Makefile.local b/Makefile.local +index a890df2..9b3db5e 100644 +--- a/Makefile.local ++++ b/Makefile.local +@@ -286,6 +286,7 @@ notmuch_client_srcs =3D \ + notmuch-reply.c \ + notmuch-restore.c \ + notmuch-search.c \ ++ structured-output.c \ + notmuch-setup.c \ + notmuch-show.c \ + notmuch-tag.c \ +diff --git a/structured-output.h b/structured-output.h +new file mode 100644 +index 0000000..b43afe0 +--- /dev/null ++++ b/structured-output.h +@@ -0,0 +1,64 @@ ++/* notmuch - Not much of an email program, (just index and search) ++ * ++ * Copyright =C2=A9 2009 Carl Worth ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see http://www.gnu.org/licenses/ . ++ * ++ * Author: Carl Worth ++ */ ++ ++#include "notmuch-client.h" ++ ++/* structured formatting, useful for JSON, S-Expressions, ... ++ ++- initial_state: is called to create a state object, that is passed to all= + invocations. This should be used to keep track of the output file and ever= +ything else necessary to correctly format output. ++- map: is called when a new map (associative array, dictionary) is started= +. map_key and the primitives (string, number, bool) are used alternatingly = +to add key/value pairs. pop is used to close the map (see there). This func= +tion must return a nesting level identifier that can be used to close all n= +ested structures (maps and lists), backing out to the returned nesting leve= +l. ++- list: is called when a new list (array, vector) is started. the primitiv= +es (string, number, bool) are used consecutively to add values to the list.= + pop is used to close the list. This function must return a nesting level i= +dentifier that can be used to close all nested structures (maps and lists),= + backing out to the returned nesting level. ++- pop: is called to return to a given nesting level. All lists and maps wi= +th a deeper nesting level must be closed. ++- number, string, bool: output one element of the specific type. ++ ++All functions should use state to insert delimiters etc. automatically whe= +n appropriate. ++ ++Example: ++int top, one; ++top =3D map(state); ++map_key(state, "foo"); ++one =3D list(state); ++number(state, 1); ++number(state, 2); ++number(state, 3); ++pop(state, one); ++map_key(state, "bar"); ++map(state); ++map_key(state, "baaz"); ++string(state, "hello world"); ++pop(state, top); ++ ++would output JSON as follows: ++ ++{"foo": [1, 2, 3], "bar": { "baaz": "hello world"}} ++ ++ */ ++typedef struct structure_printer { ++ int (*map)(void *state); ++ int (*list)(void *state); ++ void (*pop)(void *state, int level); ++ void (*map_key)(void *state, const char *key); ++ void (*number)(void *state, int val); ++ void (*string)(void *state, const char *val); ++ void (*bool)(void *state, notmuch_bool_t val); ++ void *(*initial_state)(const struct structure_printer *sp, FILE *outpu= +t); ++} structure_printer_t; ++ ++ +--=20 +1.7.10.4