source: mainline/uspace/app/bithenge/print.c@ 23db8aa

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 23db8aa was 842ed146, checked in by Sean Bartell <wingedtachikoma@…>, 13 years ago

Bithenge: use indentation in tree output

  • Property mode set to 100644
File size: 5.3 KB
Line 
1/*
2 * Copyright (c) 2012 Sean Bartell
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup bithenge
30 * @{
31 */
32/**
33 * @file
34 * Write a tree as JSON or other text formats.
35 * @todo Allow more control over the printing style, and handle printing in
36 * limited space.
37 */
38
39#include <errno.h>
40#include <stdio.h>
41#include "blob.h"
42#include "print.h"
43#include "tree.h"
44
45typedef struct {
46 bithenge_print_type_t type;
47 bool first;
48 int depth;
49} state_t;
50
51static int print_node(state_t *, bithenge_node_t *);
52
53static void newline(state_t *state)
54{
55 printf("\n");
56 for (int i = 0; i < state->depth; i++) {
57 printf(" ");
58 }
59}
60
61static void increase_depth(state_t *state)
62{
63 state->depth++;
64}
65
66static void decrease_depth(state_t *state)
67{
68 state->depth--;
69}
70
71static int print_internal_func(bithenge_node_t *key, bithenge_node_t *value, void *data)
72{
73 state_t *state = (state_t *)data;
74 int rc = EOK;
75 if (!state->first)
76 printf(",");
77 newline(state);
78 state->first = false;
79 bool add_quotes = state->type == BITHENGE_PRINT_JSON
80 && bithenge_node_type(key) != BITHENGE_NODE_STRING;
81 if (add_quotes)
82 printf("\"");
83 rc = print_node(state, key);
84 if (rc != EOK)
85 goto end;
86 if (add_quotes)
87 printf("\"");
88 printf(": ");
89 rc = print_node(state, value);
90 if (rc != EOK)
91 goto end;
92end:
93 bithenge_node_dec_ref(key);
94 bithenge_node_dec_ref(value);
95 return rc;
96}
97
98static int print_internal(state_t *state, bithenge_node_t *node)
99{
100 int rc;
101 printf("{");
102 increase_depth(state);
103 state->first = true;
104 rc = bithenge_node_for_each(node, print_internal_func, state);
105 if (rc != EOK)
106 return rc;
107 decrease_depth(state);
108 if (!state->first)
109 newline(state);
110 state->first = false;
111 printf("}");
112 return EOK;
113}
114
115static int print_boolean(state_t *state, bithenge_node_t *node)
116{
117 bool value = bithenge_boolean_node_value(node);
118 switch (state->type) {
119 case BITHENGE_PRINT_PYTHON:
120 printf(value ? "True" : "False");
121 break;
122 case BITHENGE_PRINT_JSON:
123 printf(value ? "true" : "false");
124 break;
125 }
126 return EOK;
127}
128
129static int print_integer(state_t *state, bithenge_node_t *node)
130{
131 bithenge_int_t value = bithenge_integer_node_value(node);
132 printf("%" BITHENGE_PRId, value);
133 return EOK;
134}
135
136static int print_string(state_t *state, bithenge_node_t *node)
137{
138 const char *value = bithenge_string_node_value(node);
139 printf("\"");
140 for (string_iterator_t i = string_iterator(value); !string_iterator_done(&i); ) {
141 wchar_t ch;
142 int rc = string_iterator_next(&i, &ch);
143 if (rc != EOK)
144 return rc;
145 if (ch == '"' || ch == '\\') {
146 printf("\\%lc", (wint_t) ch);
147 } else if (ch <= 0x1f) {
148 printf("\\u%04x", (unsigned int) ch);
149 } else {
150 printf("%lc", (wint_t) ch);
151 }
152 }
153 printf("\"");
154 return EOK;
155}
156
157static int print_blob(state_t *state, bithenge_node_t *node)
158{
159 bithenge_blob_t *blob = bithenge_node_as_blob(node);
160 aoff64_t pos = 0;
161 char buffer[1024];
162 aoff64_t size = sizeof(buffer);
163 int rc;
164 printf(state->type == BITHENGE_PRINT_PYTHON ? "b\"" : "\"");
165 do {
166 rc = bithenge_blob_read(blob, pos, buffer, &size);
167 if (rc != EOK)
168 return rc;
169 for (aoff64_t i = 0; i < size; i++)
170 printf("\\x%02x", (unsigned int)(uint8_t)buffer[i]);
171 pos += size;
172 } while (size == sizeof(buffer));
173 printf("\"");
174 return EOK;
175}
176
177static int print_node(state_t *state, bithenge_node_t *tree)
178{
179 switch (bithenge_node_type(tree)) {
180 case BITHENGE_NODE_INTERNAL:
181 return print_internal(state, tree);
182 case BITHENGE_NODE_BOOLEAN:
183 return print_boolean(state, tree);
184 case BITHENGE_NODE_INTEGER:
185 return print_integer(state, tree);
186 case BITHENGE_NODE_STRING:
187 return print_string(state, tree);
188 case BITHENGE_NODE_BLOB:
189 return print_blob(state, tree);
190 }
191 return ENOTSUP;
192}
193
194/** Print a tree as text.
195 * @param type The format to use.
196 * @param tree The root node of the tree to print.
197 * @return EOK on success or an error code from errno.h. */
198int bithenge_print_node(bithenge_print_type_t type, bithenge_node_t *tree)
199{
200 state_t state = {type, true, 0};
201 return print_node(&state, tree);
202}
203
204/** @}
205 */
Note: See TracBrowser for help on using the repository browser.