diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-02 10:28:58 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2007-12-02 10:28:58 +0000 |
commit | 33d4f6f29fc6cf4da1fdf382d547061e65bd8f9f (patch) | |
tree | 5e5c1233cd7e3268c1f0b5bf1c141b828b2700d3 | |
parent | bbedfc8f3a0213c29a7a04df3827f807a89c42de (diff) | |
download | mailutils-33d4f6f29fc6cf4da1fdf382d547061e65bd8f9f.tar.gz mailutils-33d4f6f29fc6cf4da1fdf382d547061e65bd8f9f.tar.bz2 |
*** empty log message ***
-rw-r--r-- | mailbox/cfg_format.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/mailbox/cfg_format.c b/mailbox/cfg_format.c new file mode 100644 index 000000000..780013bfb --- /dev/null +++ b/mailbox/cfg_format.c @@ -0,0 +1,144 @@ +/* cfg_print.c -- convert configuration parse tree to human-readable format. + Copyright (C) 2007 Free Software Foundation, Inc. + + GNU Mailutils 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, 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/>. +*/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <mailutils/stream.h> +#include <mailutils/error.h> +#include <mailutils/cfg.h> +#include <mailutils/argcv.h> +#include <mailutils/nls.h> + +struct tree_print +{ + unsigned level; + mu_stream_t stream; + char *buf; + size_t bufsize; +}; + +static void +format_level (struct tree_print *tp) +{ + int i; + for (i = 0; i < tp->level; i++) + mu_stream_sequential_write (tp->stream, " ", 2); +} + +static void +format_label (struct tree_print *tp, const char *label) +{ + size_t size; + int quote; + char *p; + + size = mu_argcv_quoted_length (label, "e); + if (quote) + size += 2; + size++; + if (size > tp->bufsize) + { + p = realloc (tp->buf, size); + if (!p) + { + mu_stream_sequential_printf (tp->stream, "%s\n", + _("ERROR: not enough memory")); + return; + } + tp->bufsize = size; + tp->buf = p; + } + + p = tp->buf; + if (quote) + { + tp->buf[0] = '"'; + tp->buf[size-2] = '"'; + p++; + } + tp->buf[size-1] = 0; + mu_argcv_quote_copy (p, label); + mu_stream_sequential_write (tp->stream, tp->buf, size - 1); +} + +static int +format_node (const mu_cfg_node_t *node, void *data) +{ + struct tree_print *tp = data; + + if (node->locus.file) + mu_stream_sequential_printf (tp->stream, "# %d \"%s\"\n", + node->locus.line, node->locus.file); + format_level (tp); + switch (node->type) + { + case mu_cfg_node_undefined: + mu_stream_sequential_printf (tp->stream, "%s", + _("ERROR: undefined statement")); + break; + + case mu_cfg_node_tag: + { + mu_stream_sequential_write (tp->stream, node->tag_name, + strlen (node->tag_name)); + if (node->tag_label) + { + mu_stream_sequential_write (tp->stream, " ", 1); + format_label (tp, node->tag_label); + } + mu_stream_sequential_write (tp->stream, " {", 2); + tp->level++; + } + break; + + case mu_cfg_node_param: + mu_stream_sequential_write (tp->stream, node->tag_name, + strlen (node->tag_name)); + if (node->tag_label) + { + mu_stream_sequential_write (tp->stream, " ", 1); + format_label (tp, node->tag_label); + mu_stream_sequential_write (tp->stream, ";", 1); + } + break; + } + mu_stream_sequential_write (tp->stream, "\n", 1); + return MU_CFG_ITER_OK; +} + +static int +format_node_end (const mu_cfg_node_t *node, void *data) +{ + struct tree_print *tp = data; + tp->level--; + format_level (tp); + mu_stream_sequential_write (tp->stream, "};\n", 3); + return MU_CFG_ITER_OK; +} + +void +mu_cfg_format_tree (mu_stream_t stream, mu_cfg_tree_t *tree) +{ + struct tree_print t; + t.level = 0; + t.stream = stream; + t.buf = NULL; + t.bufsize = 0; + mu_cfg_preorder (tree->node, format_node, format_node_end, &t); + free (t.buf); +} |