*** empty log message ***
Showing
1 changed file
with
144 additions
and
0 deletions
mailbox/cfg_format.c
0 → 100644
1 | /* cfg_print.c -- convert configuration parse tree to human-readable format. | ||
2 | Copyright (C) 2007 Free Software Foundation, Inc. | ||
3 | |||
4 | GNU Mailutils is free software; you can redistribute it and/or | ||
5 | modify it under the terms of the GNU General Public License as | ||
6 | published by the Free Software Foundation; either version 3, or (at | ||
7 | your option) any later version. | ||
8 | |||
9 | This program is distributed in the hope that it will be useful, but | ||
10 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | General Public License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU General Public License | ||
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #ifdef HAVE_CONFIG_H | ||
19 | # include <config.h> | ||
20 | #endif | ||
21 | #include <mailutils/stream.h> | ||
22 | #include <mailutils/error.h> | ||
23 | #include <mailutils/cfg.h> | ||
24 | #include <mailutils/argcv.h> | ||
25 | #include <mailutils/nls.h> | ||
26 | |||
27 | struct tree_print | ||
28 | { | ||
29 | unsigned level; | ||
30 | mu_stream_t stream; | ||
31 | char *buf; | ||
32 | size_t bufsize; | ||
33 | }; | ||
34 | |||
35 | static void | ||
36 | format_level (struct tree_print *tp) | ||
37 | { | ||
38 | int i; | ||
39 | for (i = 0; i < tp->level; i++) | ||
40 | mu_stream_sequential_write (tp->stream, " ", 2); | ||
41 | } | ||
42 | |||
43 | static void | ||
44 | format_label (struct tree_print *tp, const char *label) | ||
45 | { | ||
46 | size_t size; | ||
47 | int quote; | ||
48 | char *p; | ||
49 | |||
50 | size = mu_argcv_quoted_length (label, "e); | ||
51 | if (quote) | ||
52 | size += 2; | ||
53 | size++; | ||
54 | if (size > tp->bufsize) | ||
55 | { | ||
56 | p = realloc (tp->buf, size); | ||
57 | if (!p) | ||
58 | { | ||
59 | mu_stream_sequential_printf (tp->stream, "%s\n", | ||
60 | _("ERROR: not enough memory")); | ||
61 | return; | ||
62 | } | ||
63 | tp->bufsize = size; | ||
64 | tp->buf = p; | ||
65 | } | ||
66 | |||
67 | p = tp->buf; | ||
68 | if (quote) | ||
69 | { | ||
70 | tp->buf[0] = '"'; | ||
71 | tp->buf[size-2] = '"'; | ||
72 | p++; | ||
73 | } | ||
74 | tp->buf[size-1] = 0; | ||
75 | mu_argcv_quote_copy (p, label); | ||
76 | mu_stream_sequential_write (tp->stream, tp->buf, size - 1); | ||
77 | } | ||
78 | |||
79 | static int | ||
80 | format_node (const mu_cfg_node_t *node, void *data) | ||
81 | { | ||
82 | struct tree_print *tp = data; | ||
83 | |||
84 | if (node->locus.file) | ||
85 | mu_stream_sequential_printf (tp->stream, "# %d \"%s\"\n", | ||
86 | node->locus.line, node->locus.file); | ||
87 | format_level (tp); | ||
88 | switch (node->type) | ||
89 | { | ||
90 | case mu_cfg_node_undefined: | ||
91 | mu_stream_sequential_printf (tp->stream, "%s", | ||
92 | _("ERROR: undefined statement")); | ||
93 | break; | ||
94 | |||
95 | case mu_cfg_node_tag: | ||
96 | { | ||
97 | mu_stream_sequential_write (tp->stream, node->tag_name, | ||
98 | strlen (node->tag_name)); | ||
99 | if (node->tag_label) | ||
100 | { | ||
101 | mu_stream_sequential_write (tp->stream, " ", 1); | ||
102 | format_label (tp, node->tag_label); | ||
103 | } | ||
104 | mu_stream_sequential_write (tp->stream, " {", 2); | ||
105 | tp->level++; | ||
106 | } | ||
107 | break; | ||
108 | |||
109 | case mu_cfg_node_param: | ||
110 | mu_stream_sequential_write (tp->stream, node->tag_name, | ||
111 | strlen (node->tag_name)); | ||
112 | if (node->tag_label) | ||
113 | { | ||
114 | mu_stream_sequential_write (tp->stream, " ", 1); | ||
115 | format_label (tp, node->tag_label); | ||
116 | mu_stream_sequential_write (tp->stream, ";", 1); | ||
117 | } | ||
118 | break; | ||
119 | } | ||
120 | mu_stream_sequential_write (tp->stream, "\n", 1); | ||
121 | return MU_CFG_ITER_OK; | ||
122 | } | ||
123 | |||
124 | static int | ||
125 | format_node_end (const mu_cfg_node_t *node, void *data) | ||
126 | { | ||
127 | struct tree_print *tp = data; | ||
128 | tp->level--; | ||
129 | format_level (tp); | ||
130 | mu_stream_sequential_write (tp->stream, "};\n", 3); | ||
131 | return MU_CFG_ITER_OK; | ||
132 | } | ||
133 | |||
134 | void | ||
135 | mu_cfg_format_tree (mu_stream_t stream, mu_cfg_tree_t *tree) | ||
136 | { | ||
137 | struct tree_print t; | ||
138 | t.level = 0; | ||
139 | t.stream = stream; | ||
140 | t.buf = NULL; | ||
141 | t.bufsize = 0; | ||
142 | mu_cfg_preorder (tree->node, format_node, format_node_end, &t); | ||
143 | free (t.buf); | ||
144 | } |
-
Please register or sign in to post a comment